Home » vue » How to change/trigger HTML DOM after getting ajax response in Vue

How to change/trigger HTML DOM after getting ajax response in Vue

Posted by: admin November 26, 2021 Leave a comment

Questions:

I am new to Vue. I struggling and trying last half day not got any solution.
Here, I need to change todos text automatically based ajax response.
Using setInterval need to update vue instance and change HTML DOM as well.
When I update todo object, can’t change the DOM automatically

<div id="app">
      <ul>
        <li v-for="question in todos.text">
          {{ question.text }}
        </li>
      </ul>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: function () {
            return { 
                message: 'You loaded this page on ' + new Date().toLocaleString(),
               todos: 
                  { 
                    Event: 'Event1',
                    text: [
                      { text: 'Learn JavaScript1' },
                      { text: 'Learn Vue1' },
                      { text: 'Build something awesome1' }
                    ] 
                }
            }           
        },
        mounted: function() {
            setInterval(function () {
                axios({
                  method: 'post',
                  url: 'test.php',
                  data: {
                    firstName: 'Fred',
                    lastName: 'Flintstone'
                  }
                }).then(response => {
                    console.log(response.data);
                    this.todos = response.data;
                    Vue.set(this, todos, response.data ); 
                  })
                  .catch(err => {
                    console.log(err);
                  });
            }, 5000);
        }
    })
</script>
Answers:

The scope of this is bound to Window instead of your Vue instance.

mounted: function() {
  console.log(this); // Vue
  setInternval(function() {
    console.log(this); // Window
  }, 1000);
  setInterval(() => {
    console.log(this); // Vue
  }, 1000);
}

You had the right idea with your axios promises, .then(response => { .. }) in using the arrow function to preserve the scope of this but you didn’t apply it to setInterval.

If for some reason you really like the look of setInterval(function() { .. }), or you need this to be the Window object, you can create a variable and assign it to this outside of the setInterval function.

mounted: function() {
  const vThis = this; // Vue
  setInterval(function() {
    axios({..})
      .then(response => {
        vThis.todos = response.data;
        console.log(this); // Window
        console.log(vThis); // Vue
      })
      .catch(error => {

      });
  }, 5000);
}