SalvadorViramontes
SalvadorViramontes

Reputation: 580

EventEmitter in child component does not refresh value in parent ngIf (Angular 9)

I have an Angular Module with a child component. This component shows an animation made with GSAP library, when it ends it should hide this component and show a webpage.

Child Component

import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { gsap } from "gsap";

@Component({
  selector: 'child-component',
  templateUrl: 'child-component.html',
  styleUrls: ['child-component.css']
})
export class ChildComponent implements OnInit {
  @Output() public show = new EventEmitter<boolean>();

  constructor() { }

  ngOnInit(): void {
    var tl = gsap.timeline();
    var arg = this.show;
    gsap.set("#animation", ...);
    ...
    gsap.set("#animation", { duration: 2, delay: 10, onCompleteParams: [arg], onComplete: this.endAnimation });
    tl.play();

  }
  public endAnimation(status: EventEmitter<boolean>): void {
    status.emit(false);
  }

App Component

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: 'app.html',
  styleUrls: ['app.css']
})
export class AppComponent {
  public title = 'mySite';
  public showAnimation: boolean = true;

  constructor( ){
  }

  public hideAnimation(value: boolean) {
    this.showAnimation = value;
  }
}

Parent Template:

<child-component (show)="hideAnimation($event)" *ngIf="showAnimation"></child-component>

<div class="webpage" *ngIf="!showAnimation">
...
</div>

The issue here is that the EventEmitter sends the value to the parent component, but for some reason, this value doesn't update and the animation doesn't hide. I'm afraid that i'm missing some trivial mistake and should resolve very quickly. Please if someone can solve this problem I'll be very grateful. Note: I'm using Angular 9.

Upvotes: 1

Views: 1990

Answers (2)

wessam yaacob
wessam yaacob

Reputation: 937

I think calling endAnimation from gsap breaks out of Angular zone and there is no change detection call happen after firing hideAnimation to update showAnimation so you have some options

1) use ChangeDetectorRef

constructor(private cd: ChangeDetectorRef) {
  }

  public hideAnimation(value: boolean) {
    this.showAnimation = value;
    this.cd.detectChanges();
  }

2) use NgZone

 constructor(@Inject(ElementRef) private elementRef: ElementRef, private zone: NgZone) { }

  ngOnInit() {
    var arg = this.show;

    gsap.from("#logo", { duration: 3, x: 300, opacity: 0, scale: 0.5, 
      onCompleteParams: [arg,this.zone], onComplete: this.endAnimation });
  }

  public endAnimation(status: EventEmitter<boolean>,zone): void {
    zone.run(() => {
      status.emit(false)
    })
  }

Upvotes: 4

Piyush Jain
Piyush Jain

Reputation: 1986

your EventEmitter variable is

@Output() public show = new EventEmitter<boolean>();

but you are emitting value like this.

public endAnimation(status: EventEmitter<boolean>): void {
  status.emit(false);
}

status is a local variable .

you should do it like this.

public endAnimation(): void {
  this.show.emit(false);
}

Let me know if you have any doubt.

Upvotes: 0

Related Questions