Codemirror does not refresh the contents of the textarea until its clicked or if I use the JSON.parse on the contents while setting

I am developing a web application using Vuejs/Nuxtjs within that I have some textarea which is controlled by CodeMirror for beautification purposes. The problem I am facing is that when the content of the CodeMirror changes then it is not reflected on the CodeMirror textarea unless I click on it or if I use the JSON.parse while setting the value in Watch. If I click on it then it reflects the changes and everything is correctly working.

Following is the textarea which is governed by CodeMirror:

<textarea
    ref="input"
    :value="$store.state.modules.MyModules.input"
    class="form-control"
    placeholder="Input"
    spellcheck="false"
    data-gramm="false"
/>

Following is the code sample where I am loading the contents to CodeMirror if the values changes using the Vuejs Watch function:

data () {
    return {
        inputEditor: null
    }
},
watch: {
    '$store.state.modules.MyModules.input' (value) {
        if (value !== this.inputEditor.getValue()) {
            this.inputEditor.setValue(value)
        }
    }
},

mounted () {
    this.inputEditor = CodeMirror.fromTextArea(this.$refs.testInput, {
        mode: "applicaton/ld+json",
        beautify: { initialBeautify: true, autoBeautify: true },
        lineNumbers: true,
        indentWithTabs: true,
        autofocus: true,
        tabSize: 2,
        gutters: ["CodeMirror-lint-markers"],
        autoCloseBrackets: true,
        autoCloseTags: true,
        styleActiveLine: true,
        styleActiveSelected: true,
        autoRefresh: true,
    });

    // On change of  input call the function
    this.inputEditor.on("change", this.createTestData);

    // Set the height for the input CodeMirror
    this.inputEditor.setSize(null, "75vh");

    // Add the border for all the CodeMirror textarea
    for (const s of document.getElementsByClassName("CodeMirror")) {
        s.style.border = "1px solid black";
    }
  }

I found issues similar to this and tried the following things but still no luck:

  1. Trying to refresh the contents within the watch method:

watch: {
    '$store.state.modules.MyModules.input' (value) {
        const vm = this
        if (value !== this.inputEditor.getValue()) {
            this.inputEditor.setValue(value)
            setTimeout(function () {
                vm.inputEditor.refresh()
            }, 1)
        }
    }
},
  1. Trying to use the autorefresh within my CodeMirror but that also did not work.

What worked for me is that when setting the value I need to use the JSON.parse within the watch method. If I do that then It’s working correctly but I do not want to do that:

watch: {
    '$store.state.modules.MyModules.input' (value) {
        const vm = this
        if (value !== this.inputEditor.getValue()) {
            this.inputEditor.setValue(JSON.parse(value))
        }
    }
},

Can someone please inform me why the CodeMirror data will not be updated if I do not do JSON.parse?

editor.refresh() is not what you’re looking for here. editor.save() will update the textarea with the editor’s current content.

@marijn Thanks a lot for taking your time to respond.

I tried your answer but still, the issue does not seem to resolve. I tried to add following within my watch function:

setTimeout(function () {
  vm.inputEditor.save()
}, 1)

But even after this, the content of the textarea is updated only if I click on it otherwise data is not updated. Still a bit confused about what could be wrong.

Bit more background:
Currently, I have 2-page applications page1 and page2. The CodeMirror textarea is present on page2. The user provides information on page1 and they submit the data is stored in Vuex Store and the user will be navigated to page2. Using the nuxtjs application router option I am navigating the user from page1 to page2. Do you think this navigating could be causing the issue?

@marijn Looking forward to some suggestions.

@marijn Can you please provide some solution to this issue? Because I am still unable to find a work-around. It would be really nice if you can provide some solution. Thanks a lot in advance.

No, I can’t. How you cant to schedule calls to .save() is something you’ll have to work out yourself. A timeout with a 1 millisecond delay is probably not it, though.

@marijn Thanks a lot for your reponse. Your one small comment helped me.
Actually, it was the issue due to 1 time out. I should give at least 100 or 500 so as for it to work.

Following worked for me:

 setTimeout(function () {
                vm.inputEditor.refresh()
            }, 100)
1 Like