Lombardinho
Lombardinho

Reputation: 95

hide child component in a parent component

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

Answers (4)

Amer
Amer

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

Airas Yaqub
Airas Yaqub

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

JSmith
JSmith

Reputation: 4808

I would try using BehaviourSubjectlike

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

Balastrong
Balastrong

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

Related Questions