Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2: How to detect changes in an array? (@input property)

I have a parent component that retrieves an array of objects using an ajax request.

This component has two children components: One of them shows the objects in a tree structure and the other one renders its content in a table format. The parent passes the array to their children through an @input property and they display the content properly. Everything as expected.

The problem occurs when you change some field within the objects: the child components are not notified of those changes. Changes are only triggered if you manually reassign the array to its variable.

I'm used to working with Knockout JS and I need to get an effect similar to that of observableArrays.

I've read something about DoCheck but I'm not sure how it works.

like image 619
pablolmedorado Avatar asked Mar 22 '17 20:03

pablolmedorado


People also ask

How to detect changes in array in Angular?

To detect changes in an array from an @input property with Angular, we can get the latest value in the ngDoCheck method. //... export class AppComponent implements OnInit { constructor(private iterableDiffers: IterableDiffers) { this. iterableDiffer = iterableDiffers.

What triggers change detection in angular?

By default, angular will run the change detector every time @Input() data is changed or modified. But with OnPush strategy, the change detector is only triggered if the data passed on @Input() has a new reference.

How does angular 7 detect changes?

To run the change detector manually: Inject ChangeDetectorRef service in the component. Use markForCheck in the subscription method to instruct Angular to check the component the next time change detectors run. On the ngOnDestroy() life cycle hook, unsubscribe from the observable.


2 Answers

OnChanges Lifecycle Hook will trigger only when input property's instance changes.

If you want to check whether an element inside the input array has been added, moved or removed, you can use IterableDiffers inside the DoCheck Lifecycle Hook as follows:

constructor(private iterableDiffers: IterableDiffers) {     this.iterableDiffer = iterableDiffers.find([]).create(null); }  ngDoCheck() {     let changes = this.iterableDiffer.diff(this.inputArray);     if (changes) {         console.log('Changes detected!');     } } 

If you need to detect changes in objects inside an array, you will need to iterate through all elements, and apply KeyValueDiffers for each element. (You can do this in parallel with previous check).

Visit this post for more information: Detect changes in objects inside array in Angular2

like image 100
seidme Avatar answered Oct 12 '22 14:10

seidme


You can always create a new reference to the array by merging it with an empty array:

this.yourArray = [{...}, {...}, {...}]; this.yourArray[0].yourModifiedField = "whatever";  this.yourArray = [].concat(this.yourArray); 

The code above will change the array reference and it will trigger the OnChanges mechanism in children components.

like image 22
Wojtek Majerski Avatar answered Oct 12 '22 14:10

Wojtek Majerski