Search code examples
angulareventemitter

Listenning to EventEmitter doesnt work with observer (Alpha 44)


I put my data in a service so if it change every component listen to it and update their component with the new Data.

but everything is wired together and i don't receive any error but it doesn't receive the event when it's fired!

Here is the service:

    import {EventEmitter, Injectable} from 'angular2/angular2';
    import {PlayerModel} from '../../models/players/players.ts';

    @Injectable()
    export class PlayerService {
        playerListModified: EventEmitter = new EventEmitter();
        players: Array<PlayerModel> = new Array<PlayerModel>();

        addPlayer(player: PlayerModel) {
            this.players.push(player);
            this.playerListModified.next(this.players);
        }
    }

Here is the Component that Listen to the Service Change

    import {Component, Input, NgFor} from 'angular2/angular2';
    import {PlayerModel} from '../../models/players/player.ts';
    import {PlayerService} from '../../services/players/playerService.ts';

    @Component({
        selector: 'best-score-board',
        templateUrl: 'app/components/leaderboards/bestScoreBoard.html',
        directives: [NgFor],
        providers: [PlayerService]
    })
    export class BestScoreBoardComponent {
        players: Array<PlayerModel>;

        constructor(playerService: PlayerService) {
            playerService.playerListModified.observer({
                next: (players) => console.log('test2')
            });

            this.players = playerService.players;
        }
    }


What am i doing wrong ?


**EDIT** 

Here is where i call the service

import {Component, Output, EventEmitter} from 'angular2/angular2';
import {PlayerModel} from '../../models/players/player.ts';
import {PlayerService} from '../../services/players/playerService.ts';

@Component({
     selector: 'create-player-form',
     templateUrl: 'app/components/players/createPlayerForm.html',
     providers: [PlayerService]
 })
export class CreatePlayerFormComponent {
    playerService: PlayerService;

    constructor(playerService: PlayerService) {
        this.playerService = playerService;
    }

    createPlayer(name, score) {
        this.playerService.addPlayer(new PlayerModel(name.value, score.value));
        name.value = '';
        score.value = '0';
    }
 }

if i do a console.log in my service i do receive the PlayerModel.


Solution

  • When you add ProviderService to the providers in Component decorator the new instance of ProviderService is created for this component (and its children).

    @Component({
      // ...
      // new instance of PlayerService will be created 
      // for BestScoreBoardComponent
      providers: [PlayerService]
    })
    export class BestScoreBoardComponent { /* ... */ }
    
    @Component({
      // ...
      // and again new instance of PlayerService will be created
      // at this time for CreatePlayerFormComponent
      providers: [PlayerService]
    })
    export class CreatePlayerFormComponent { /* ... */ }
    

    If you want to use single instance of PlayerService for both of these components, you should specify it in providers of their common parent component or in bootstrap function.

    @Component({
      // ... 
      // providers: [PlayerService] <- you should remove this line
    })
    export class BestScoreBoardComponent { /* ... */ }
    
    @Component({
      // ... 
      // providers: [PlayerService] <- and this line too
    })
    export class CreatePlayerFormComponent { /* ... */ }
    
    // ...
    
    bootstrap(AppComponent, [PlayerService]); // <-- Here you go.