I want to pass a value to the child component. this value is an Observable, so I use async pipe.
<child [test]="test$ | async"></child>
test$ is just a normal observable variable, that emits values after a period of time (3000 ms), simulating an API request to the server.
this.test$=timer(3000).pipe(
mapTo("value")
)
in child component, I just want to check test value
@Input() test: any;
constructor(){
console.log("child/test", this.test); //null
setTimeout(()=>console.log("child/test (timeout)", this.test),4000) //value
if(this.test){
//maintain and check `this.test`
//this code will not run, because at this point `this.test` is null.
//we don't know the exact time that `this.test` will have a value
//this causes that `this.test` is wrong
this.checked=true
}
}
<div *ngIf="checked">{{test}}</div>
I don't want to change the type of test to be Observable and subscribe to it.
I want to receive the final value directly.
and I don't want to modify the edit component at all.
using ChangeDetectorRef to manually trigger the change detector is not
@Input() test$:Observable
constructor(){
this.test$.subscribe(v=>this.test=v)
}
I also made this stackblitz to check the value changing among all the compoonent's hooks.
async pipe will return null when no value is emitted by Observable yet. So, the value of test in child component is:
undefined in constructor because @Input() variables are not assigned at this statenull after that (e.g. first onChanges hook or onInit hook`) when no value is emitted by the Observablevalue when the Observable emit new valueNow, you should either create child component only when test variable is not null with *ngIf, or handle correctly the state of child component with nullable test (e.g. Add a progress bar when test is null). The choice is up to you.
<ng-container *ngIf=(test$ | async) as test; else defaultTmpl>
<child [test]="test"></child>
</ng-container>
<ng-template #defaultTmpl>Default Template<ng-template>
For more details please take a look: https://ultimatecourses.com/blog/angular-ngif-async-pipe
Much easier solution:
(test$ | async) || defaultTestValue
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