I have an array items of objects:
data() {
return {
items: [
{
id: 101,
firstName: 'Mohammed',
lastName: 'Chang',
dob: '1995-03-21'
},
{
id: 102,
firstName: 'John',
lastName: 'Smith',
dob: '1989-10-11'
},
{
id: 103,
firstName: 'Lulu',
lastName: 'Lemon',
dob: '1945-01-29'
},
]
}
},
If I use a regular watch, and try to compare the items, because the items are objects, they will reference the same thing, so they will always return as unchanged:
watch: {
items: {
handler: function(revised, original) {
for (let i = 0; i < revised.length; i++) {
// check each item in revised to see if it's changed from original
if (this.isChanged(original, revised[i])) {
axios.put(URL + '/' + revised[i].id, revised[i]);
}
}
},
deep: true
}
},
methods: {
isChanged(original, item) {
// this function won't work because item is an object
// which will be referenced in original, so it will always
// be a match, i.e. not changed
for (let i = 0; i < revised.length; i++) {
// found a matching ID in the original
if (original[i].id === revised.id) {
// compare the item against the original and return
// true for changed and false for not changed
return JSON.stringify(original[i]) !== JSON.stringify(item);
}
// no match? assume true
return true;
}
}
}
}
If I use a watch like this, by referencing each item directly, then this will work:
watch: {
'items.0': {
handler: function(revised) {
axios.put(URL + '/' + revised.id, revised);
},
deep: true
},
'items.1': {
handler: function(revised) {
axios.put(URL + '/' + revised.id, revised);
},
deep: true
},
'items.2': {
handler: function(revised) {
axios.put(URL + '/' + revised.id, revised);
},
deep: true
}
},
However this approach is not very practical. What if I dynamically add an item to the array? It won't have a watcher.
Is there a way to do a watch like above items.# but using wildcards or regular expressions?
Because there's no way to compare the original object, do most developers just update each element in the entire array with its own PUT call? This seems wasteful, especially if dealing with many very large objects.
watch: {
items: {
handler: function(revised) {
// no way to know which item is changed, so just
// update each item - wasteful, I know
for (let i = 0; i < revised.length; i++) {
axios.put(URL + '/' + revised[i].id, revised[i]);
}
},
deep: true
}
},
deep:trueafterhandler: {}...There's probably a better way to do this, but it's hard to determine how you're updating them so we can advise. Can you include that?deep: truestill exhibits the same functionality. Have added put statements.