Reputation: 2986
I have struggling to make it work in Angular. I have a host component (parent) which is using a child one to render a dropdown list. The source of the list is been passed from the parent. So for example, if the parent pass 5 items on the source property, the child component will render 5 options for the dropdown list.
this is part the code where I call the child component:
parent.component.html
<ng-container>
<th mat-header-cell *matHeaderCellDef>
<app-column-header
[id]="column.id"
[name]="column.name"
[source]="myObject.options"
></app-column-header>
</th>
</ng-container>
parent.component.ts
export class ParentComponent {
@ViewChild(ChildComponent) ChildComponent;
// more code
private updateChildSource() {
this.child.updateDataSource(myObject.options);
}
}
This is working OK so far.
NOW, the challenges I am having is that the list of items to be passed needs to be dynamic (myObject.options). So, for example, the first time lets says I am passing 5 items. Angular takes those 5 items and render the child component properly. However, once the child component is already rendered and if I changes the source to be 2 items instead of 5 from the parent and pass the new source, the child component is not rendering the new items (2).
child.component.ts
export class ColumnHeaderComponent implements OnInit, OnChanges {
@Input() id: string;
@Input() name: string;
@Input() source: any[];
childField: any;
ngOnInit(): void {
const options = this.doStuffHere(this.source);
this.childField= {
id: this.id,
options,
};
}
updateDataSource(newSource: Option[]): void {
console.log(`print call from parent. old options:
${JSON.stringify(this.childField.options)} - new options: ${JSON.stringify(newSource)}`);
this.source= newSource;
const options = this.doStuffHere(this.source);
this.childField= {
id: id,
options,
};
}
ngOnChanges(changes: SimpleChanges) {
console.log('changed');
for (const propName in changes) {
const chng = changes[propName];
const cur = JSON.stringify(chng.currentValue);
const prev = JSON.stringify(chng.previousValue);
console.log(`${propName}: currentValue = ${cur}, previousValue = ${prev}`);
}
}
}
As mentioned before, the child component is receiving the original and new items, even the ngOnChanges method is capturing it and printing the values properly. But for some reason I don't know yet the child component is still rendering the old items (5) instead of the new ones (2).
Not sure, if I am missing something here? Or the question is clear enough to illustrated the problem I am facing.
Could you point me to the correct direction how to solve this? Thanks in advance.
Upvotes: 0
Views: 3515
Reputation: 76
As said Marek you can directly pass the list from your parent component as the input of your child component. The [list]="list" notation is already reactive. Then you'll just have to use the list in the drop-down in your child component.
Note : Not useful here, but as @Input you can set a function instead of a variable. It will be triggered every time the input value change.
Upvotes: 3