victorjaquez
victorjaquez

Reputation: 3

Angular Parent/Children click events: Show child component in parent after click event on a different child in parent component?

I'm a couple weeks into Angular 7 and I'm struggling to hide/show a child component <app-child-2> in a Parent component <parent> after a click event on a separate child <app-child-1> in the same parent component.

All the children card divs only render if they have data, this is done via a ngIf method from the parent shouldCardRender() and outputsMapToRead('Child 1'). The shouldCardRender() method is used to check if the data object groupName is checked: true via another method in the parent called this.checkIfCardHasAnyCheckedValues() before showing. If false it doesn't render on parent, if true another method runs that feeds all the true data into the child component.

Here's how both children are set in the parent.

<div *ngIf="shouldCardRender('Child 1')">
        <app-child-1 [outputsArray]="outputsMapToRead.get('Child 1')" [rawData]="rawData"></app-child-1>
</div>

<div *ngIf="shouldCardRender('Child 2')">
        <app-child-2 [outputsArray]="outputsMapToRead.get('Child 2')" [rawData]="rawData"></app-child-2>
</div>

I believe the [outputsArray]outputsMapToRead.get('Child #') is the data that categories the groupName for that child and the feeds the true data for the child depending on the groupName.

Here's an example of the data object that shouldCardRender() & this.checkCardValues() check. If checked is true, card renders. Please note that a normal object, has close to 20 objects inside of it, if those objects are true, a different method gives those cards access to data for the child to plug and play, right now all 'checked` keys are set to true.

outputsMap.set('Child 1',  [
    {
      name: 'fraudScore',
      friendlyName: 'Fraud Score',
      checked: true, 
      groupName: 'Child 1'
    }, 
    .....
  ]);

outputsMap.set('Child 2',  [
    {
      name: 'displayName',
      friendlyName: 'Display Name',
      checked: true, 
      groupName: 'Child 2'
    }, 
    .....
  ]);

My problem is that there is a button on the <app-child-1> thats says "Show <app-child-2>". I am struggling to get <app-child-2> to hide/show since that currently depends on the shouldCardRender and the data object from [outputsArray].

I believe I have to use @Output and EventEmitter on child and have it bubble up to the parent. But I'm hitting a road block with the logic needed to turn data to false to hide component. I also thought about changing the checked key to false and making method on the child or parent? that turns checked into true.

Any help would be appreciated, thanks.

Upvotes: 0

Views: 8335

Answers (1)

Nimer Awad
Nimer Awad

Reputation: 4199

Okay, before start talking about solution; i wanna describe something important about parent/child components.

  • You should use @Input() decoration to pass data from Parent to Child.
  • You should use @Output() decoration to pass data from Child to Parent.

You can read more about on the documentation.

  • @Input() represented in html using property binding like:

<child1 [name]="'testing'"></child1>

Which means child1 component has a variable called name that get its value from parent component.

  • @Output() represented in html using event binding like:

<child1 (rebuild)="doSomething($event)"></child1>

Which means child1 component has an EventEmitter called rebuild that returns a value of some type and we catch this value in parent component using $event.

How can this help you?

I made you an example how to handle your case, check it here.

each child component in this example has a button to show other component, on this button click; child component will pass a boolean value that will be catch from parent and used in *ngIf.

I hope that help you will.

Upvotes: 1

Related Questions