I have been looking for some reason of this behavior, the value of a Input() property in a child component 'Param' is not been updated at the right time, I need to use the updated value to call a service as a parameter. By clicking the 'update child value' button the LOG B is displayed first (with an old value) after that the LOG A is displayed (LOG A it's in the setter of the property).
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
@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 have first the value of the param updated and then use that value as a parameter on a service. LOG A then LOG B
Using @Input()
implies you are relying on Angular2 mechanism to propagate the value changes, which means you should not expect your changes to take immediate effect. In fact, your this.parentParam = 9;
will go through a whole Angular2 cycle to update your child's param
and the showParam()
function will always be executed first.
To achieve your task, you have 2 choices:
1) Add 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 invoked by Angular2 every time there's a change to any @Input
. However, if you have more than 1 input, this could be problematic.
ngOnChanges(changes) {
console.log(this.param); // new value updated
}