vue.jsnuxt.jstextareacodemirrorui-codemirror

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?


Solution

  • Providing the answer as it can be helpful to someone else in the future:

    Actually the vm.inputEditor.refresh() will work only problem was that I was using it with setTimeout 0.001s which is way to quick for to refresh.

    After trying a lot I found my stupid mistake. I tried to change it to 1000 or 500 and it works now.

    Following is the change:

    setTimeout(function () {
     vm.inputEditor.refresh()
    }, 1000)