A. Vreeswijk
A. Vreeswijk

Reputation: 954

Angular EventEmitter get data

I just started with learning Angular, but I ran into a problem that I have been trying to work out for the last couple hours. I have a parent child relation between 2 components. Now I want to share a boolean variable from my master to a child. The child should display a text when its true and if it is false, show a different text. Here is the @Output code:

import {Component, EventEmitter, OnInit, Output} from '@angular/core';
import {Offer} from "../../../models/offer";

@Component({
  selector: 'app-overview2',
  templateUrl: './overview2.component.html',
  styleUrls: ['./overview2.component.css']
})
export class Overview2Component implements OnInit {

  public offers: Offer[] = [];

  constructor() { }

  ngOnInit(): void {
    for (let i = 0; i < 8; i++) {
      this.addRandomOffer();
    }
  }

  public addRandomOffer(): void {
    let offer = Offer.createRandomOffer();
    this.offers.push(offer);
  }

  public highlightClickedRow(offer :Offer) {
    for (let i = 0; i < this.offers.length; i++) {
      if (this.offers[i] != offer) {
        this.offers[i].rowClicked = false;
      }
      else {
        this.offers[i].rowClicked = true;
        this.selected.emit(true);
      }
    }
  }

  @Output('update')
  selected: EventEmitter<boolean> = new EventEmitter<boolean>();

}

Then in my HTML of the parent, I have the following:

<div>
  <app-detail2 [offerSelected]="selected"></app-detail2>
</div>

In the TypeScript of the child, I collect the @Output as follows:

@Component({
  selector: 'app-detail2',
  templateUrl: './detail2.component.html',
  styleUrls: ['./detail2.component.css']
})
export class Detail2Component implements OnInit {

  @Input() offerSelected: EventEmitter<boolean> = new EventEmitter<boolean>();

  constructor() {
  }

  ngOnInit(): void {
  }

}

Then in the child HTML I want to use the boolean to decide to show a label using the following code:

<div *ngIf="offerSelected.prototype then thenBlock else elseBlock"></div>
<br>
{{offerSelected.prototype}}
<ng-template #thenBlock><label  id="lblSomethingSelected">Something has been selected yet</label></ng-template>
<ng-template #elseBlock><label  id="lblNothingSelected">Nothing has been selected yet</label></ng-template>

But the problem I am having is that offerSelected is always false. Now I think its because offerSelected is of the type EventEmitter<boolean> and not a real boolean. But how can I use it like I want to? Please let me know!

Upvotes: 1

Views: 960

Answers (1)

Brandon Taylor
Brandon Taylor

Reputation: 34553

Just to capture the discussion in an answer...

When you have a parent-child relationship between components and are passing data from the parent to the child, you don't need an EventEmitter. You only need to set a property on the parent, and then specify an @Input to receive the value in the child.

// parent.component.ts

selected: boolean;

// child.component.ts

@Input()
offerSelected: boolean;

With that change, the HTML in the child can be:

<div *ngIf="offerSelected then thenBlock else elseBlock"></div>

<ng-template #thenBlock>
  <label id="lblSomethingSelected">Something has been selected</label>
</ng-template>
<ng-template #elseBlock>
  <label id="lblNothingSelected">Nothing has been selected yet</label>
</ng-template>

If you're sending data from the child to the parent, then you need an EventEmitter.

Upvotes: 1

Related Questions