45

My angular application stuck with a issue, i used input as array and pushed a value to the array when the click event arise. But the ngOnChanges not firing when the array push is done. Is there a way to fire ngOnChange

My Code is ts file is

@Component({
  selector: 'adv-search',
  templateUrl: './app/modules/result.html'
})

export class InputComponent {
  @Input() metas:any=[];

  ngOnChanges() {
    console.log(this.metas);
  }
}

My Selector Tag

<adv-search [metas] = "metaIds"></adv-search>

Click Event Code

insertIds(id:any) {
   metaIds.push(id);
}
2
  • where you have used insterIds event ? Commented Apr 5, 2017 at 6:38
  • You change array in main component Or in your child component? Commented Apr 5, 2017 at 6:40

3 Answers 3

88

Angular change detection only checks object identity, not object content. Inserts or removals are therefore not detected.

What you can do is to copy the array after each update

insertIds(id:any) {
  this.metaIds.push(id);
  this.metaIds = this.metaIds.slice();
}

or use IterableDiffer to check for changes inside InputComponent in ngDoCheck like NgFor does.

Sign up to request clarification or add additional context in comments.

14 Comments

whats the meaning of copy array here ?
The array will be another one (another object instance) but with the original content. Angular will recognize this change.
are you sure that by doing so angular will recognize the changes ?
@PardeepJain thanks for the hint, didn't pay attention. Updated my answer.
There is nothing like that in Angular, mostly for performance reasons. The best way is usually to have an Observable in the object and subscribe to it where you want to get notified. For arrays, there is angular.io/api/core/IterableDiffers. You can check the source of *ngFor about how to use it.
|
14

If you reassign your metaIds array, the ngOnChanges lifecycle event will be fired. You can deconstruct your array into a new array.

insertIds(id:any){
    this.metaIds = [...this.metaIds, id];
}

Comments

12

@GünterZöchbauer 's answer is completely correct. However, I would like to add a alternative/supplement to copying the whole array. Using the same example from the question.

<adv-search [metas] = "metaIds"></adv-search>

altered to

<adv-search [metas] = "{trackBy: metaIds.length, metaIds: metaIds}"></adv-search>

Where length here is the equivalent of the *ngFor trackBy function for the component. With this the ngOnChanges occurs with content length changes.

If used in combination with the *ngFor trackBy method there should be some performance benefits as the whole array's bound templates are not recalculated (no screen/content flickering).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.