CodeMirror 6: Proper way to listen for changes

What is the intended way to listen for changes to editor state?

I need to sync the document contents with some other state, and I noticed that while I can listen for input events on the editor DOM, the state.doc doesn’t hold the correct value until at least a microtask after the event fires. So my code to listen for changes looks like this:

    this._editorView.dom.addEventListener('input', async (e) => {
      e.stopPropagation();
      await 0;
      this._value = this._editorView.state.doc.toString();
      this.dispatchEvent(new InputEvent('input'));
    });

Is this the right way?

Absolutely not. Not only is it a giant hack, it’ll also fail to notice programmatic changes. Depending on what you are trying to do, it may make sense to provide a dispatch function when creating your editor view, or register a view plugin that starts the action you want when its update method is called.

Ah, sorry, I thought dispatch was more meant for customizing how transactions were applied. I was looking through the docs for a more notification-only API point.

Is this._editorView.state.doc.toString() an ok way to get the document contents, or is there something better?

That’s the way. Though for giant documents it’s going to do quite a lot of string concatenation, so depending on your use case you might not want to constantly do it when you can avoid it.

1 Like