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