I have a nested array and I need to add new subject for multiple persons, but for keeping it simple I will add new subject to Jon only.
[
{
gender: "male",
persons: [
{
name: "Jon",
subjects: [
{ subName: "maths", marks: "45" },
{ subName: "phy", marks: "47" },
],
},
],
},
{
gender: "female",
persons: [
{
name: "Amily",
subjects: [{ subName: "bio", marks: "43" }],
},
],
},
]
I will add subject on button click.
addSubject() {
/* This doesn't work */
let newData = [...this.data];
newData[0].persons[0].subjects.push({ subName: "chem", marks: "50" });
this.data = newData;
}
It works if I use this.push("data.0.persons.0.subjects", { subName: "chem", marks: "50" }); but if I need to add subjects to multiple persons,this method will update property every time. Above could accumulate all changes in temporary array only update once.
Render
<template is="dom-repeat" items="[[data]]">
<div>Gender: [[item.gender]]</div>
<template is="dom-repeat" items="[[item.persons]]">
<div>Name: [[item.name]]</div>
<template is="dom-repeat" items="[[item.subjects]]">
<div>Subject: [[item.subName]], [[item.marks]]</div>
</template>
</template>
</template>
If I try rendering simpler data, then its working fine
<template is="dom-repeat" items="[[simpleData]]">
<div>Subject: [[item.subName]], [[item.marks]]</div>
</template>
static get properties() {
return {
simpleData: {
type: Array,
notify: true,
value: () => [
{ subName: "math", marks: "11" },
{ subName: "phy", marks: "22" },
],
},
}
addSubjectInSimple() {
let newData = [...this.simpleData];
newData.push({ subName: "chem", marks: "50" });
this.simpleData = newData;
}
Try adding the
mutable-dataattribute on your dom-repeat. This tells polymer to look out for deep changes any time the object changes. (You still need to callthis.setorthis.notifyPathto trigger the dom update.)Polymer tries very hard (sometimes too hard) to not update the dom when it doesn't think it needs to, which is why it does dirty checking on
dom-repeats. You are using a more modern approach when you create yournewDataobject and change it, which modern browsers can usually handle, but Polymer needs "permission" to use that approach.Note: Object spread
...is doing a shallow copy of your object, not a deep clone. (See this answer for more on that.)