tinymce-react: TinyMCE in IonModal fails to start when initialised a second time

What is the current behavior? I have an Editor on an IonModal if I open the modal twice the Editor crashes and fails to render.

Please provide the steps to reproduce and if possible a minimal demo of the problem via codesandbox.io or similar. You can find a minimal example of this here: https://codesandbox.io/s/jolly-fire-d7l52?file=/src/App.js If you press “Show Modal” twice it crashes with

tinymce.min.js:2 Uncaught TypeError: Cannot read property 'open' of undefined

What is the expected behavior?

The Editor should show up.

Which versions of TinyMCE, and which browser / OS are affected by this issue? Did this work in previous versions of TinyMCE or tinymce-react?

Google Chrome | 87.0.4280.141

@tinymce/tinymce-react 3.9.0 @ionic/react 5.5.2 @ionic/react-hooks 0.0.8 @ionic/react-route 5.3.4

I figure it’s a problem with the IonModal and my current workaround to use the Material-UI Modal works. I just thought I should let someone know.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 4
  • Comments: 21 (9 by maintainers)

Most upvoted comments

Thanks for the reply @Marruixu. Yes I eventually also tried using tinymce directly with a textarea (no react wrapper) but bumped into other problems (missing themes, icons) and even though I tried importing them, the current project’s gulp setup is not ready for this approach… I put a pin on it because of the time that this adaptation might take.

Still, it seems that the solution is simply not using the library, which is a pitty …

I’m suffering from the same issue. Although the editor is not inside a modal, it’s an element that either gets added or removed from the DOM. As soon as it’s added a second time, I’m faced with the “Cannot read property ‘open’ of undefined” error. @Marruixu I’ve tried sending a different id on each mount but without any luck…

@1dl3 I think I have a solution: https://codesandbox.io/s/tinymce-issues204-fixed-kvw6t

I will put in a PR.

Hi, I share a workaround that I have quickly come up with, which I hope it may help or inspire for those using something like Ionic 5 Modal with React:

Essentially consists in changing the attribute id every time, for example, by increasing a counter

  • Use normal tinymce package, not wrapper tinymce-react, and in the module which holds the editor import it like: import tinymce from 'tinymce/tinymce';
  • If you are using apiKey method, this is not required: At the end of <head> tag in index.html add <script src="%PUBLIC_URL%/tinymce/tinymce.js"></script> and place the unminfied (or minfied, then change URL accordingly) resources at /public/tinymce
  • Set a <textarea id={"myTinyMCE" + initCounter} defaultValue={content} /> inside IonModal
  • Define 2 states for initCounter and content (content is for showing a more complete example, but not required) const [initCounter, setInitCounter] = useState<number>(0); and const [content, setContent] = useState<string>(); (assuming Typescript here)
  • Define useEffect based on IonModal isOpen property
useEffect(() => {
  if (isOpen) {
    // increment counter to avoid TypeError
    setInitCounter(initCounter + 1);
            
    setTimeout(() => {
      tinymce.init({
        ...
        selector: '#myTinyMCE' + (initCounter + 1), // see that for some reason I didn't investigaded, initCounter value was not updated in this particular code block
        ...
        });
        setContent("<p>Hello world</p>") // defaultValue
      }, 500) // allow some time, otherwise "real" content is not loaded in DOM
    }
  }, [isOpen]); // I don't recommend using empty array as a "componentDidMount" because is fired by the IonModal parent even without opening modal, unexpectedly
  • later on, if needed, when submitting or whatever, you can read the content like this tinymce.get("myTinyMCE" + initCounter).getContent(); and use setContent() for example

Sure this can be improved, but as a start point I hope it helps other people solving this problem without having to look out for another editor until the wrapper works for this situations.

Well my best guess is that something to do with shadow-dom is interacting badly with TinyMCE because it seems to be having trouble getting things that are normally available globally on the window like document and styleSheets.

I tried it with the latest editor unminfied here: https://codesandbox.io/s/wizardly-cherry-pl159?file=/src/App.js

Honestly I have no idea how to fix this.