5

I simply want to update a boolean value in my parent component on click of a button in my child component. I have a slide-out child component that I hide and show based on a dynamic ngClass. The class is set based on the boolean value from the parent. However when I close that component from a button in the child, I want to update the boolean value in the parent:

The parent component typescript:

export class AppComponent implements OnInit   {

  showFlyout: boolean

  constructor() {}

  ngOnInit() {
    this.showFlyout = false;
  }
}

And parent html:

<main>

  <button (click)="showFlyout = !showFlyout"><i class="fa fa-check"></i>Show Flyout</button>

  {{showFlyout}}

  <app-child id="flyout" [ngClass]="showFlyout ? 'active' : ''"></app-child>

</main>

The child component typescript:

export class ActivateFlyoutComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

  closeActivationFlyout() {
    const flyout = document.getElementById('flyout');
    flyout.classList.remove('active');
  }

}

And child component html:

<button (click)="closeFlyout()">Close</button>

Here's a Stackblitz. You can see clicking the parent button properly toggles the class but how can I update that boolean from click in the child and therefore make the closeActivationFlyout() method unnecessary in the child component?

4
  • use @Output decorator with EventEmitter of type boolean Commented Apr 4, 2018 at 19:55
  • My answer forgot to change the state on the child element. Please accept Jun's answer. Commented Apr 4, 2018 at 20:07
  • @JordanBarber manipulating the dom directly is not the proper way to do such thing, Commented Apr 4, 2018 at 20:28
  • @RandyCasburn, that is precisely why I asked this question. I knew DOM manipulation was the wrong way and the answer I received has helped me to eliminate that. Thanks for your help! Commented Apr 4, 2018 at 21:06

2 Answers 2

5

Use @Output() like the others have mentioned, but it needs to emit an event and you also need to check for the event being triggered in the parent html.

Here's a working StackBlitz

In the child component.

@Output() onCloseClick = new EventEmitter();

closeFlyout() {
  this.onCloseClick.emit();
}

And in the parent components html.

<app-child id="flyout" [ngClass]="showFlyout ? 'active' : ''" (onCloseClick)="showFlyout = false"></app-child>

You can also create a function in the parent component, and trigger that like (onCloseClick)="doFunction()"

Sign up to request clarification or add additional context in comments.

Comments

1

You can use two-way databinding to make it works:

AppComponent:

<app-child id="flyout" [(showFlyoutModel)]="showFlyout" [ngClass]="showFlyout ? 'active' : ''"></app-child>

ChildComponent :

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

    @Component({
      selector: 'app-child',
      templateUrl: './child.component.html'
    })
    export class ChildComponent implements OnInit {
      @Input()
      showFlyoutModel;

      @Output()
      showFlyoutModelChange = new EventEmitter<boolean>();
      constructor() { }

      ngOnInit() {
      }

      closeFlyout() {
        this.showFlyoutModelChange.emit(!this.showFlyoutModel);
      }

    }

https://stackblitz.com/edit/angular-v95emc?file=app%2Fchild-component%2Fchild.component.ts

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.