Reputation: 95
I want to render a child component in a parent only when the child has finished an http call, but it doesn't work for me, the child component isn't displayed...
child selector in parent component
<app-child-component *ngIf="alert" (alert)="propagar($evento)"></app-child-component >
export class ParentComponent implements OnInit {
alert = false;
propagar(evento: boolean) {
this.alert = evento;
}
export class ChildComponent implements OnInit {
@Output alert = new EventEmitter<boolean>();
ngOnInit() {
this.childComponentService.getSomething().subscribe(response => {
if(this.response.code === 200)
this.alerta.emit(true);//here I just want the child component to be displayed
})
}
}
But it doesn't work, the child component is never shown even though the service responds correctly
Upvotes: 2
Views: 2092
Reputation: 6706
You can't do that this way because the component will be rendered (i.e. initialized) only once *ngIf
's condition is true.
Instead, I suggest handling it completely within your child component, by mapping the HTTP call observable to boolean
once the HTTP call is finished, to determine if the component content should be rendered or not.
You can try the following:
parent.component.html
<app-child-component></app-child-component>
child.component.ts
export class ChildComponent implements OnInit {
ready$: Observable<boolean>;
ngOnInit() {
// Assign it to an observable to avoid handling subscribe/unsubscribe within the component class.
ready$ = this.childComponentService
.getSomething()
.pipe(map((response) => response.code === 200));
}
}
child.component.html
<!-- Wrap all your child component template with ng-container -->
<ng-container *ngIf="ready$ | async">
<!-- Your child components stuff here which will be rendered only once the HTTP call is completed -->
</ng-container>
Upvotes: 2
Reputation: 87
You are using structural directive on child component. If set to "false" initially it won't even initiate child component hence no httpcall in child will execute. What you can do is use "[hidden]" property instead of "*ngIf" with initial value set to true. This way when child component will emit output event the binded property with "hidden" can set to be false and child component will be viewed in DOM.
child selector in parent component
<app-child-component [hidden]="alert" (alert)="propagar($evento)"></app-child-component >
export class ParentComponent implements OnInit {
alert = true;
propagar(evento: boolean) {
this.alert = evento;
}
export class ChildComponent implements OnInit {
@Output alert = new EventEmitter<boolean>();
ngOnInit() {
this.childComponentService.getSomething().subscribe(response => {
if(response.code === 200)
this.alert.emit(false);
})
}
}
Upvotes: 1
Reputation: 4808
I would try using BehaviourSubject
like
your alertService:
alert = new BehaviourSubject(false)
your child component
alert:BehaviourSubject<boolean>;
constructor(private childComponentService:childComponentService, private alertService:alertService){
this.alert = alertService.alert
}
...
this.childComponentService.getSomething.subscribe(
() => this.alert.next(true));
your html:
<app-child-component *ngIf="alert | async"></app-child-component >
Upvotes: 0
Reputation: 4464
If you want to access the object response
of your subscription, you need to remove this.
inside your if statement.
this.childComponentService.getSomething().subscribe(response => {
if(response.code === 200) // <<----- removed this. here
this.alerta.emit(true);
})
Upvotes: 0