I have a QueryList
in a component. I am adding dynamically other components, that will be present in the QueryList
, but if I subscribe to the changes
of the QueryList
, nothing happens. I thought it is because I subscribed in ngAfterViewInit
, but the QueryList
is undefined
yet in ngOnInit
.
Here I have the plunkr.
code:
@Component({
...
})
export class AppComponent {
@ViewChildren(ControlFactoryDirective) factories:
QueryList<ControlFactoryDirective>
ngAfterViewInit() {
this.factories.changes.subscribe(() => {
console.log('changed')
})
}
}
The thing is, the list that comes to your factories
property is already pre-populated. So you just don't have a chance to subscribe to its changes before it's populated for the first time. But all changes that happen later are coming through to your subscriber, of course.
Here is the plunkr with your example updated - notice that factories now has a setter which proves that it's prepopulated (you normally don't need it in a real app, that's for finding out only what value comes from the framework)
I think it's a totally valid behavior. So in ngAfterViewInit
, loop over values in the QueryList and do the same thing you are about to do in the subscriber:
ngAfterViewInit() {
this.processChildren(); // first call to processChildren
this.factories.changes.subscribe(_ =>
this.processChildren() // subsequent calls to processChildren
);
}
private processChildren(): void {
console.log('Processing children. Their count:', this.factories.toArray().length)
}
You can also add startWith(undefined)
like this:
ngAfterViewInit() {
this.factories.changes.pipe(startWith(undefined)).subscribe(() =>
{
console.log('changed')
})
}
This will trigger the subscription handler immediately.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With