Skip to content
Advertisement

Cannot set property ‘innerHTML’ of null”, Vue

I have two components for editing JSON objects. And i have a button that switches between these two. Here is the html code:

<v-btn @click="switchConfigClicked">Switch config</v-btn>
<h4 class="switchButtonInfo">Switch between editor/plain-text</h4>
<v-btn class="switchEditButton" @click="switchEditButtonClicked">Switch Editor</v-btn>
<div class= "editorComponents">
  <div v-if="showEditComponents" class="editor">
    <div v-if="showJsonEditor">
      <JsonEditor is-edit="true" v-model="editedConfig" ></JsonEditor>
    </div>
    <div v-if="showTextEditor">
      <textarea id="myTextArea" cols=75 rows=100></textarea>
    </div>
  </div>

//Javascript code

switchEditButtonClicked: function(){

  this.showTextEditor = !this.showTextEditor;
  this.showJsonEditor = !this.showJsonEditor;

  if (this.showTextEditor) {

    this.editedConfig = JSON.stringify({"hello":"test"}, undefined, 4);

    document.getElementById('myTextArea').innerHTML = this.editedConfig;

  }
  else{
    //this.editedConfig = JSON.parse(this.edite)
  }

},

Start value for showJsonEditor = true, showTextEditor = false gives me the error:

Cannot set property ‘innerHTML’ of null”, Vue

i tried setting the the code like below

window.onload = function() {
    // all of your code goes in here
    // it runs after the DOM is built
}

No error is shown but also no text is shown.

Test case

i commented out these two lines from switchConfigClicked:

//this.showTextEditor = !this.showTextEditor;
//this.showJsonEditor = !this.showJsonEditor;

and reversed the boolean start values for showJsonEditor = false, showTextEditor = true

Result

Text is shown in the textEditor with no errors..

Conclusion

I have a feeling that it has to do with my v-if, when showTextEditor is set to false and then changed to true maybe we are trying to put the text in before the new DOM is created? Not really sure why and how to fix this..

Advertisement

Answer

The textarea is not yet available/rendered at this point (deferred by v-if), try querying for it inside Vue.nextTick.

Defer the callback to be executed after the next DOM update cycle. Use it immediately after you’ve changed some data to wait for the DOM update.

switchEditButtonClicked: function () {
  this.showTextEditor = !this.showTextEditor;
  this.showJsonEditor = !this.showJsonEditor;

  if (this.showTextEditor) {
    this.editedConfig = JSON.stringify({
        "hello": "test"
      }, undefined, 4);

    Vue.nextTick(() => {
      // Or better yet use a `ref`
      document.getElementById('myTextArea').innerHTML = this.editedConfig;
    });

  } else {
    //this.editedConfig = JSON.parse(this.edite)
  }

}
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement