I'm trying to get an Angular component Input variable to detect changes. The input variable is a array of objects and I need to detect what object changes and what property that is changing. I'm using this to change behaviour of form controls in a child component from a parent component.
I've tried the following solutions:
Detect changes in objects inside array in Angular2
constructor(private differs: KeyValueDiffers) {
}
ngOnInit() {
this.objDiffer = {};
this.list.forEach((elt) => {
this.objDiffer[elt] = this.differs.find(elt).create(null);
});
}
However the function .create requires TrackByFunction and it's not possible to assign this.objDiffer[elt] since it's a object and not a list of objects.
Detect changes in objects inside array in Angular2
private objDiffers: Array<KeyValueDiffer<string, any>>;
constructor(
private differs: KeyValueDiffers) {
this.itemGroups = new Array<ItemGroup>();
this.differ = this.differs.find(this.itemGroups).create();
}
public ngOnInit(): void {
this.objDiffers = new Array<KeyValueDiffer<string, any>>();
this.itemGroups.forEach((itemGroup, index) => {
this.objDiffers[index] = this.differs.find(itemGroup).create();
});
}
ngDoCheck(): void {
this.itemGroups.forEach((itemGroup, index) => {
const objDiffer = this.objDiffers[index];
const objChanges = objDiffer.diff(itemGroup);
if (objChanges) {
objChanges.forEachChangedItem((changedItem) => {
console.log(changedItem.key);
});
}
});
}
This let's me get the value changed, but not the actually object that I'm looking for.
http://blog.bogdancarpean.com/how-to-watch-for-changes-an-arrayobject-on-angular-2/
export class ArrayWatchDemoComponent implements DoCheck {
@Input() datasource: Array<any> = [];
differ: any;
constructor(differs: IterableDiffers) {
this.differ = differs.find([]).create(null);
}
ngDoCheck() {
const change = this.differ.diff(this.datasource);
console.log(change);
}
This solution is only console logging null values. But it triggers when I change the property of the object in the input array. I know you can use forEachAddedItem or forEachRemovedItem but this doesn't fix the solution.
https://www.concretepage.com/angular/angular-keyvaluediffers
@Input() empArray: Employee[];
empDifferMap = new Map<number, any>();
empMap = new Map<number, Employee>();
arrayDiffer: any;
constructor(private kvDiffers: KeyValueDiffers) {}
ngOnInit() {
this.empArray.forEach(emp => {
this.empDifferMap[emp.id] = this.kvDiffers.find(emp).create();
this.empMap[emp.id] = emp;
})
}
ngDoCheck() {
for (let [key, empDiffer] of this.empDifferMap) {
let empChanges = empDiffer.diff(this.empMap.get(key));
if (empChanges) {
empChanges.forEachChangedItem(record => {
console.log('Previous value: ' + record.previousValue);
console.log('Current value: ' + record.currentValue);
});
}
}
}
This was the recent one I've tried, but I didn't get it to work and got the error
"ERROR in src/app/forms/dynamic-form/dynamic-form.component.ts(39,34): error TS2569: Type 'Map' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators."
I've also tried to create the array again.
//this.list = [{foo: true}];
this.list = [];
this.list = [{foo: false}];
But that's a ugly solution and makes the elements in the child component flicker.
I expect the child component to detect changes in a object that is in a array which is a input. The child component doesn't detect changes.