Title: Vue.js not detecting data change with push()
Tags: javascript;arrays;vue.js;ecmascript-6;vuejs2
Question: I have this method that sets a data structuce in my attributes object.
setAttributes(data) {
const attr = data.attributes;
attr.forEach(attribute =&gt; {
attribute.attributes.forEach(item =&gt; {
if (!this.attributes[attribute.name]) {
this.$set(this.attributes, attribute.name, {
name: attribute.name,
attributes: []
});
}
if (!this.attributes[attribute.name].attributes[item.id]) {
this.$set(this.attributes[attribute.name].attributes, item.id, {
name: item.name.value,
attributes: []
});
}
this.attributes[attribute.name].attributes[item.id].attributes.push(item);
});
Everything works except the last line this.attributes[attribute.name].attributes[item.id].attributes.push(item); where Vue doesn't detect the data change and the array is still empty.
As I am aware, push() should make Vue detect a data change or is that not true?
Comment: do you mean that vue doesn't detect that there is some changes in attributes and should re-render ?

Comment: You are right Vue should be able to detect changes. Can you please make a simplified example in an online editor in order to help you?

Comment: @KrisD.J.taking a look now

Comment: @SaJed `this.attributes[attribute.name].attributes[item.id].attributes` of each item is still an empty array, after this method is run on all data - that's basically the problem :)

Comment: And if I console log `this.attributes[attribute.name].attributes[item.id].attributes`, I can see that the items get pushed to the array, but Vue doesn't seem to detect that.

Comment: @roliroli I have posted an answer with the solution, thanks for the help though, I appreciate it :)


Here is another answer: Got it working with this code:
setAttributes(data) {
const attr = data.attributes;
attr.forEach(attribute =&gt; {
const name = attribute.name
.toLowerCase()
.replace(/[^a-z0-9 -]/g, '')
.replace(/\s+/g, '_');
if (!this.attributes[name]) {
this.$set(this.attributes, name, {
name: attribute.name,
attributes: {}
});
attribute.attributes.forEach(item =&gt; {
if (!this.attributes[name].attributes[item.id]) {
this.$set(this.attributes[name].attributes, item.id, {
name: item.name.value,
attributes: []
});
}
this.attributes[name].attributes[item.id].attributes.push(item);
});
The problem was that attributes was set as an array and not an object in the first if statement.

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 6, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2019:00:07/10/19', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<javascript><arrays><vue.js><ecmascript-6><vuejs2>', 'Title': 'Vue.js not detecting data change with push()', 'ViewCount': 135, 'id': 56966647, 'user_AboutMe': '', 'user_AccountId': 6264064.0, 'user_DisplayName': 'Kris D. J.', 'user_Reputation': 594.0, 'user_Views': 42.0, 'user_id': 7983254.0}}