react-codemirror2 icon indicating copy to clipboard operation
react-codemirror2 copied to clipboard

load editor content, event editorDidConfigure not fired

Open flashpixx opened this issue 6 years ago • 8 comments

Hello,

I try to load within the Controlled version data during the mount process

<CodeMirror
     options={{
          theme: "cobalt",
          lineNumbers: true,
          indentUnit: 4
     }}

     editorDidMount={editor => {
          fetch( encodeURI( this.state.sourceurl + "/" + this.state.name) )
          .then( result => { return result.text(); } )
          .then( data => { console.log("mount: " + data); editor.setValue(data); } );
     }}

     editorDidConfigure={editor => {
          console.log("configured");
     }}

     editorWillUnmount={editor => {
          console.log("unmount");
     }}
/>

The event editorDidConfigure is not fired at any time. The event editorDidMount is fired the data will be get from the ajax call, but the setValue call does not push the data to the editor component, so on the mounted component no text is shown. On the editorWillUnmount I cannot get the content with editor.getValue() because the method getValue does not exists.

flashpixx avatar May 19 '19 13:05 flashpixx

@flashpixx You'll want to delegate a callback here, especially since you have an ajax call. Per the events | editorDidMount

invoking optional next will trigger editorDidConfigure

So in this case, you'll just need to modify your editorDidMount to the following...

editorDidMount={(editor, next) => {
  fetch( encodeURI( this.state.sourceurl + "/" + this.state.name) )
  .then( result => { return result.text(); } )
  .then( data => { 
    console.log("mount: " + data); 
    editor.setValue(data);
    next(); // ready for `editorDidConfigure`
   })
}}

I should probably clear up the docs on this one as I can see it being confusing. Let me know if this helps at all?

scniro avatar May 19 '19 16:05 scniro

This does not work, I get an error.

Uncaught (in promise) TypeError: n is not a function

flashpixx avatar May 19 '19 16:05 flashpixx

@flashpixx Interesting, I just looked in the source again and the signature for editorDidMount indeed expects three parameters

editorDidMount?: (editor: codemirror.Editor, value: string, cb: () => void) => void;

Try the following?

editorDidMount={(editor, value, next) => {
  [...]
  next();

Now I definitely need to fix that documentation, yikes 😨

scniro avatar May 19 '19 16:05 scniro

This does not create any error and the editorDidConfigure is fired, but I cannot push any data into the value / editor. I try a editor.setValue(data) and a value = data call.

You can found the whole source here

flashpixx avatar May 19 '19 17:05 flashpixx

@flashpixx You appear to not be using the Controlled component correctly. You need to bind a state value and manage that manually such as the example

<CodeMirror
  value={this.state.value}
  onBeforeChange={(editor, data, value) => {
    this.setState({value});
  }}
  onChange={(editor, data, value) => {
  // most current value that's rendered
  }}
/>

editor.setValue largely goes against the pattern this library generally tries to encourage to interact with codemirror in a "react" way.

I'm not totally familiar with your usage, but it appears you'd be better served making your ajax call from the parent container, setting your local state with the data returned, and passing that to your codemirror component as a value prop

scniro avatar May 19 '19 17:05 scniro

The ajax call running outside works fine, but on this the editor needs a click to show the content. So in my case a modal (bootstrap) dialog is open, the editor is mounted but is shown with an empty content. If I click into the code field, the content is shown. Did I need to refresh the codemirror instance manually?

flashpixx avatar May 20 '19 05:05 flashpixx

@flashpixx I am a lot shorter on time these days as when I started this project. Codemirror & React APIs are moving to quickly for me to keep atop of for the day-to-day. I am looking for a co-maintainer of this project. Please contact me directly if you are interested. Thank you for understanding.

scniro avatar Jan 19 '20 16:01 scniro

The ajax call running outside works fine, but on this the editor needs a click to show the content. So in my case a modal (bootstrap) dialog is open, the editor is mounted but is shown with an empty content. If I click into the code field, the content is shown. Did I need to refresh the codemirror instance manually?

Maybe it's too late, but anyways :) I assume you are using react-bootstrap. So, you have two options here:

  1. Set animation property to false.
  2. Use onEntered callback to handle some state, let's say isEntered and show CodeMirror component if isEntered === true. But sometimes it doesn't work. So the first option is more stable, but anyways I'm sure something can be done with the second option

MikeSha avatar Jun 24 '20 09:06 MikeSha