Home > Blockchain >  Angular Input property change is not detected when I push new item in array
Angular Input property change is not detected when I push new item in array

Time:11-12

I have a list of an array(dataSource) on which I am performing Add and Delete operations. I have passed an array(dataSource) in the child component and added *ngFor loop in the child. Array I have passed as getter setter for detect @Input change.

This is my AppComponent :

<div>
    <vertital-tabs
          [config]="config"
          [dataSource]="dataSource"    <-- Array changes I want to detect in Child
          [(selectedItem)]="selectedItem">
    </vertital-tabs>

    <div style="background-color: yellow;margin: 10px">
        {{ selectedItem | json }}
     </div>
</div>

In ChildComponent (vertical-tabs) :

get dataSource(): any {
    return this._dataSource;
}

@Input() set dataSource(value: any) {
    this._dataSource = value;
    // Not called this on Add New button even if Input Datasource is changed.
    // I want this to be called on Add New Item button click....
    debugger;
}

Problem is that when I am adding a new item on the array, it is not calling the setter @Input change method. When I am deleting an item it is working fine and call @Input change.

Note: I have lot of properties as an Input in real scenario so I don't want to use ngOnChanges()

Here is an example I have created: https://stackblitz.com/edit/angular-vertical-tabs-component-split-yzynef

CodePudding user response:

Angular only checks whether the reference has changed - if it has not changed since the last check the setter will not be called.

In app.component.ts:

let nextItem = this.dataSource.length;
this.dataSource.push({
  id: nextItem.toString(),
  text: 'item '   nextItem.toString(),
  icon: 'settings',
});

Here you add something to your array instead of creating a new array and assigning it to dataSource.

In vertical-tabs.ts:

onDelete(item, index) {
  this.dataSource = this.dataSource.filter((x) => x !== item);
}

Here you create a new array and assign it to dataSource.

That's why deletion works as you expect, but adding doesn't. Copying the array and assigning it to dataSource should solve your problem:

let nextItem = this.dataSource.length;
this.dataSource = [
  ...dataSource,
  {
    id: nextItem.toString(),
    text: 'item '   nextItem.toString(),
    icon: 'settings',
  }
];
  • Related