I can't seem to trigger the parent component's async pipe from a child component to update the view. Which might sound a bit confusing but let me try to explain by showing a simplified version of my code.
If have got a class that is extended by another class.
export class ParentComponent implements OnInit{
protected subject$: BehaviorSubject<string[]>;
ngOnInit() {
this.subject$ = new BehaviorSubject<string[]>([]);
}
}
With a template that looks like:
<span *ngFor="let niceString of subject$ | async">
{{niceString}}
</span>
Extended by:
export class ChildComponent extends ParentComponent implements OnInit{
ngOnInit() {
super.ngOnInit();
this.subject$.next(['string1', 'string2']);
}
}
The template is not updated in the browser. If I would call the line with subject$.next in the parent component it would update as expected and show the two strings in the browser.
So I tried to play around with it by calling SetTimeOut with 3 seconds delay to see if somehow it was called to fast. This didn't solve the issue. I also add the subject$.next in a function in the parent that I then called from the child and also this wouldnt solve it. But if I would call the same new function in the parent class the view was updated as expected.
I also added a custom subscription in the parent that listens to the subject$ like so:
protected subjectSubscription: Subscription;
this.subjectSubscription = this.subject$.pipe(take(2)).subscribe((justChecking: string[]) => {
debugger;
});
Which will be triggered as expected but the view in the browser isnt updated with the values 'string1', 'string2'.
Am I missing something here?
(EDIT) Add StackBlitz: https://stackblitz.com/edit/angular-tt65ig
You're mixing inheritance and composition:
<app-parent>
.So you're creating two instances of the parent component:
<app-child>
in the root component template. This instance of parent is an instance of child. Its subject emits two strings, but its template, which only has <app-parent>
never displays these two strings.one by using <app-parent>
in the child component template. This instance of parent is not an instance of child. Its template displays the content of its subject, but its subject never emits anything, since it's not an instance of the child component, and only the child component contains the code to emit 2 strings.
parent
- has subject1
^
-
|
|
extends
|
| displays
child --------------------------------> parent
- emits from subject1 - has subject2
- displays content of subject2
How to fix? Don't do that. Either use inheritance, or, preferrably, use composition, but don't mix the two.