1

I know there is many similar questions about data not being updated in VueJS component but I still could not find the answer. I have the following component:

<template> <div class="mt-5"> [...] <div v-for="dataSource in dataSources" v-bind:key="dataSource.id"> {{ dataSource}} </div> [...] </div> </template> <script> import { chain, find, merge, toUpper } from "lodash"; import Mixins from "../utils/Mixins.vue"; import Pagination from "../utils/Pagination.vue"; import DataSourceTable from "./DataSourceTable.vue"; export default { mixins: [Mixins], components: { "data-source-table": DataSourceTable, "data-source-pagination": Pagination }, data: function() { return { dataSources: [], //[...] }; }, methods: { getAllDataSources(page) { //[...] }, search() { //[...] }, setSortAttribute(attribute) { //[...] }, updateDataSource(updatedDataSource){ for (let i = 0; i < this.dataSources.length; i++) { if (this.dataSources[i].id == updatedDataSource.id) { this.dataSources[i] = updatedDataSource; break; // Stop this loop, we found it! } } } }, created: function() { this.getAllDataSources(this.currentPage); // Capture updated data source via websocket listener this.$options.sockets.onmessage = function(data) { let message = JSON.parse(data.data); if (message.id == "dataSource" && message.type == "data") { let updatedDataSource = message.payload.data.listen.relatedNode; this.updateDataSource(updatedDataSource); } } } }; </script> 

In the created hook, I capture changes coming from a websocket and I update the corresponding item in the array dataSources. I can see the item is properly updated in Vue Dev Tools but it is still not updated in the component template. Example below:

enter image description here

2 Answers 2

3

This is a common mistake with vuejs. You can check the document here: Why isn’t the DOM updating? In Your case, you can use push or $set to achieve your purpose.

When you modify an Array by directly setting an index (e.g. arr[0] = val) or modifying its length property. Similarly, Vue.js cannot pickup these changes. Always modify arrays by using an Array instance method, or replacing it entirely. Vue provides a convenience method arr.$set(index, value) which is syntax sugar for arr.splice(index, 1, value).

Example:

  • Replace this.dataSources[i] = updatedDataSource;
  • By this.dataSources.splice(i, 1, updatedDataSource);
Sign up to request clarification or add additional context in comments.

Comments

0

When you modify an Array by directly setting an index (e.g. arr[0] = val) or modifying its length property. Similarly, Vue.js cannot pickup these changes. Always modify arrays by using an Array instance method, or replacing it entirely. Vue provides a convenience method arr.$set(index, value) which is syntax sugar for arr.splice(index, 1, value).

updateDataSource(updatedDataSource){ for (let i = 0; i < this.dataSources.length; i++) { if (this.dataSources[i].id == updatedDataSource.id) { //this.dataSources[i] = updatedDataSource; this.dataSources.$set(i, updatedDataSource); break; // Stop this loop, we found it! } } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.