The viewchild input property is not updated if angular 2 is needed

I was looking for the reason for this behavior, the value of the Input () property in the child component "Parameter" is not updated at the right time, I need to use the updated value to call the service as a parameter. By clicking the "Update child value" button, LOG B (with the old value) is displayed first, and then LOG A is displayed (LOG A is in the property settings).

Parent component

@Component({ selector: 'parent', template: ` <child #child [param]="parentParam"></child> <button (click)="updateChildValue()">Update child value</button> `}) export class Parent { @ViewChild('child') child: Child; public parentParam: number; public updateChildValue() { this.parentParam = 9; this.child.showParam(); } } 

child component

 @Component({ selector: 'child', template: '' }) export class Child { private _param: number; public get param() : number { return this._param; } @Input('param') public set param(v : number) { this._param = v; console.log('LOG A'); console.log(this.param); } public showParam() { console.log('LOG B'); console.log(this.param); //I need to call a service using the latest value of param here... } } 

The desired behavior is to first update the parameter value, and then use that value as a parameter in the service. LOG A, then LOG B

+5
source share
2 answers

Using @Input() implies that you rely on the Angular2 mechanism to propagate value changes, which means that you should not expect your changes to take effect immediately. In fact, your this.parentParam = 9; An entire Angular2 loop will go through to update your child param , and the showParam() function will always be executed first.

To achieve your task you have 2 options:

1) Add the parameter directly to your showParam , as in:

 // child component public showParam(newVal: number) { this._param = newVal; // do your service call here } // parent component public updateChildValue() { this.parentParam = 9; this.child.showParam(9); } 

2) Leverage ngOnChanges on your Child component. This function will be called by Angular2 every time any @Input . However, if you have more than 1 input, this can be problematic.

 ngOnChanges(changes) { console.log(this.param); // new value updated } 
+3
source

I think this is a better answer than the current accepted answer:

Angular2 + the way to achieve this is to use the ngOnChanges lifecycle hook:

 Parent component: @Component({ selector: 'parent', template: ` <child #child [param]="parentParam"></child> <button (click)="updateChildValue()">Update child value</button> `}) export class Parent { @ViewChild('child') child: Child; public parentParam: number; public updateChildValue() { this.parentParam = 9; this.child.showParam(); } } the child component: import { OnChanges, SimpleChanges, SimpleChange } from '@angular/core' @Component({ selector: 'child', template: '' }) export class Child implements OnChanges { @Input() param: number; public showParam() { console.log('LOG B'); console.log(this.param); //I need to call a service using the latest value of param here... } ngOnChanges(changes: SimpleChanges) { const c: SimpleChange = changes.param; this.param = c; } } 
+1
source

Source: https://habr.com/ru/post/1258857/


All Articles