Some doubts about the event emit in Angular 2. How exactly this example works?

I am an absolute beginner with Angular 2 and I have some doubts about how exactly works this example related how an event is emitted by the framework (I am following a tutorial).

So I have the following situation:

The main component is the app-root and contains this view:

<div class="container">
  <div class="row">
    <div class="col-xs-12">
      <app-game-control></app-game-control>
    </div>
  </div>
</div>

That, as you can see, include the <app-game-control></app-game-control> sub component. Its view only show 2 buttons inside my single page application, these:

<button
  class="btn btn-success"
  (click)="onStartGame()"
>Start Game</button>

<button class="btn btn-danger">Pause Game</button>

Clicking on the firs one it is called the related sub component controller method onStartGame(), this is the entire code of this controller:

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

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

  intervalFired = new EventEmitter<number>();
  interval;
  lastNumber = 0;


  constructor() { }

  ngOnInit() {
  }

  onStartGame() {
    this.interval = setInterval(() => {
      this.intervalFired.emit(this.lastNumber + 1);
      this.lastNumber ++;
    }, 10000);
  }

}

And here I have some doubts about what exactly happens when the button is clicked.

From what I have understood an event is simply an object that can be emitted, in this case it should be an object containing a single numeric field:

intervalFired = new EventEmitter<number>();

Is it this interpretation of event correct or am I missing something?

When the user click the button the onStartGame() is performed. This method should emit the event (doing a simple calculation of its value).

But what exactly means emit an event? Who is the recipient of this emitted event? I think that it should be the parent component controller but I am absolutly not sure about it.

How it exactly works?

2 answers

  • answered 2017-06-17 18:33 Mateusz Kocz

    When a component has an EventEmitter as one of its properties, it starts to emit events to the components using it. This is mostly the same as with the button element you used. Lets imagine the button is a component. It will be declared like that:

    @Component({
        selector: 'button',
        template: '<div (click)="onButtonClick()"></div>'
    })
    class Button {
        click = new EventEmitter();
    
        onButtonClick() {
            this.click.emit(/* an event value */)
        }
    }
    

    Then you use this button component in your GameControlComponent by listening to the click event (<button (click)="onStartGame()">).

    You can probably now understand what is emitted and who the recipient should be. In your example, the consumer of the GameControlComponent's intervalFired event should be your AppRoot component, or any other component using the <app-game-control> component.

    <div class="container">
      <div class="row">
        <div class="col-xs-12">
          <app-game-control (intervalFired)="handleInterval($event)"></app-game-control>
        </div>
      </div>
    </div>
    

    As you can see, the handleInterval function has the $event argument. The value of this argument is what your internal (GameControlComponent) component emits, ie. this.lastNumber + 1.

  • answered 2017-06-17 18:33 Aravind

    You should be using an @Output() to emit an event from a component.

    Note: @Output() intervalFired = new EventEmitter<number>(); should be the event to be emitted.

    You can handle that event in your root component as below,

    <div class="col-xs-12">
          <app-game-control (intervalFired)="intervalFired($event)" ></app-game-control>
    </div>
    

    Typescript code

    intervalFired(e){
       this.lastNumber = e;
      console.log(e)
    }
    

    LIVE DEMO