In the parent component, I've defined an Observable variable named results$, and in the view, it is utilized as follows:
controller:
this.result$ = this.firstObservable$.pipe(
combineLatestWith(
this.secondObservable$.pipe(filter((task) => !!task.key)),
),
switchMap(([first, second]: [type1, type2]) => {
// some logic here happend
map((businessFunctionResult: businessFunctionType[]) => ({
data: businessFunctionResult,
isLoading: false,
})),
catchError((error: unknown) => {
const err = error as HttpErrorResponse;
return of({ error: err, isLoading: false });
})
);
view:
<div *ngIf="result$ | async as result">
<container *ngIf="!result.isLoading && result.data">
<child-component1 [data]="result.data"></child-component1>
<child-component2 [data]="result.data"></child-component2>
...
</container>
</div>
In the child-component, an Input is present, and each child component implements the OnInit lifecycle hook. However, when the value of results changes or updates, the child components do not reflect these changes.
export class ChildComponent1
implements OnInit
{
@Input() data!: any[];
ngOnInit(): void {
console.log(this.data);
}
}
An alternative solution involves replacing ngIf with ngFor in the code. By adopting this approach, the child components are successfully updated. While this solution may seem less straightforward, but its not such a clear solution because the component will be initialized every time.
<div *ngFor="let result of [result$ | async]">
<container *ngIf="!result.isLoading && result.data">
<child-component1 [data]="result.data"></child-component1>
<child-component2 [data]="result.data"></child-component2>
</container>
</div>
I know I can use ngOnChanges in child components, but for some issues (refactoring, etc.) I don't want to do it.
I want to update the child components every time result$ has a new value.
What about to work with behaviroSubject instead of input ?
Like I would create service with behaviorSubject.
And in parent component you could set new value or even in child. It works both way.
And listen in one of that component.
Personally, I would probably not use BehaviorSubject for parent-child or child-parent communication.
Rather, I would use it in two components that don't share anything and need to pass data between them. But in your case, it seems like a good solution.