0

I've started to learn Angular2 yesterday and I'm stuck at understanding how to subscribe to an EventEmitter.

I have my layout divided in 2 part Leaderboard that show players and CreatePlayer that create a new Player.

I have a PlayerService that hold the PlayerList. So when i add a player in the CreatePlayer a new player is added in the PlayerList.

But I need to reflect the playerList change in the Layout so the Properties in the Leaderboard [players] is rebind or updated.

Here is my code:

import {Component, View} from 'angular2/angular2';
import {Header} from './header';
import {Leaderboard} from '../leaderboards/leaderboard';
import {CreatePlayer} from '../players/create-player';
import {PlayerService} from '../players/player-service';
import {Player} from '../players/player';

@Component({
    selector: 'layout',
    bindings: [PlayerService]
})
@View({
    templateUrl: './src/layout/layout.html',
    directives: [Header, Leaderboard, CreatePlayer]
})
export class Layout {
    players: Array<Player>;
    
    constructor(playerService: PlayerService) {
        this.players = playerService.players;
    }
}

import {EventEmitter} from 'angular2/angular2';
import {Player} from './player';

export class PlayerService {
    players: Array<Player>;
    playersListChange: EventEmitter;

    constructor() {       
       this.players = [];
       this.playersListChange = new EventEmitter();
    }

    addPlayer(tag: string, name: string, score: number) {
        var player = new Player();
        player.tag = tag;
        player.name = name;
        player.score = score;

        this.players.push(player);
        this.playersListChange.next(this.players);
    }
}

How do I subscribe to this playersListChange event?

I've tried in the Layout Constructor :

playerService.playersListChange.observer({ next: (value) => this.onPlayersChange(value) });

but it doesn't work.

Do you guys can tell me how do I subscribe to this EventEmitter?

EDIT:

Tried this without success:

playerService.playerListChange.toRx().subscribe(this.onPlayerListChange);
    
onPlayerListChange(value) {
    this.players = value;
}

As it raises the following type error:

TypeError: playerService.playersListChange.toRx(...).subscribe is not a function

EDIT 2:

Here is my new code but still the listenner doesn't get called! (no console.log happen) where did I do a mistake?

import {Component, View, EventEmitter, FORM_DIRECTIVES, FormBuilder,           ControlGroup, Control, Validators, NgIf} from 'angular2/angular2';
import {Player} from './player';
import {PlayerService} from './player-service';

@Component({
    selector: 'create-player',
    bindings: [PlayerService]
})
@View({
    templateUrl: './src/players/create-player.html',
    directives: [FORM_DIRECTIVES, NgIf]
})
    export class CreatePlayer {
    playerForm: ControlGroup;
    playerService: PlayerService;

    constructor(builder: FormBuilder, playerService: PlayerService) {
        this.newplayer = new EventEmitter();

        this.playerForm = builder.group({
            tag: ['', Validators.required],
            name: ['', Validators.required],
            score: ['', Validators.required]
        });

        this.playerService = playerService;
    }

    addPlayer(formValue) {
        var player = new Player();
        player.tag = formValue.tag;
        player.name = formValue.name;
        player.score = formValue.score;

        this.playerService.addPlayer(player.tag, player.name, player.score);
    }
}

import {EventEmitter} from 'angular2/angular2';
import {Player} from './player';

export class PlayerService {
    players: Array<Player>;
    playersListChange: EventEmitter;

    constructor() {
        var player = new Player();
        player.tag = "#ROCK";
        player.name = "Rookie";
        player.score = 102;
        this.players = [player];

        this.playersListChange = new EventEmitter();
    }

    addPlayer(tag: string, name: string, score: number): void {
        var player = new Player();
        player.tag = tag;
        player.name = name;
        player.score = score;
        this.players.push(player);
        this.playersListChange.next(this.players);
    }
}

import {Component, View} from 'angular2/angular2';
import {Header} from './header';
import {Leaderboard} from '../leaderboards/leaderboard';
import {CreatePlayer} from '../players/create-player';
import {Player} from '../players/player';
import {PlayerService} from '../players/player-service';
import {Observer} from 'rx.all';
 
@Component({
    selector: 'layout',
    bindings: [PlayerService]
})
@View({
    templateUrl: './src/layout/layout.html',
    directives: [Header, Leaderboard, CreatePlayer]
})
export class Layout {
    players: Array<Player>;
    playerService: PlayerService;
    playersChanged: Observer = Observer.create(
        (players: Array<Player>) => { this.playerListChange(players); },
        (error) => { },
        () => { });

    constructor(playerService: PlayerService) {
        this.players = [];
        this.playerService = playerService;
 
        this.playerService.playersListChange.toRx().subscribe(this.playersChanged);
    }

    playerListChange(players: Array<Player>) : void {
        console.log(players);
    } 
}

I tried too with

(players) => { this.playerListChange(players); },

and with

playerListChange(players) : void {
    console.log(players);
}
Vincent Doba
  • 4,343
  • 3
  • 22
  • 42
Vince
  • 1,279
  • 2
  • 20
  • 40
  • I think this line `this.players = playerService.players;` should be `this.players = playerService;`. Besides that, what ng2 version are you using? – Eric Martinez Oct 11 '15 at 22:17
  • Upgrade to a40. In a39 toRx() was returning the EventEmitter itself, it was a mistake that they solved in alpha 40. Don't get to attached to it, it will be completely removed, in fact .toRx(). was already removed in a39 from http calls, and it will dissapear from EventEmitter. – Eric Martinez Oct 11 '15 at 23:03
  • So what should be the good way of doing it if it's going to be removed? I want my model to dispatch an event when the players List change. – Vince Oct 11 '15 at 23:20
  • Sorry if I didn't myself clear. `toRx()` will be removed, but you'll still be able to subscribe to an EventEmitter. You're a doing it fine, in future releases you'll have to to subscribe directly, without `toRx()`, like `playerListChange.subscribe()`, but for now stick to `toRx()` ;) – Eric Martinez Oct 11 '15 at 23:24
  • i've switched to alpha 40. everything seems to goes right (no error) but the listenner never get called! my event is -> this.playersListChange.next(this.players); and the listener this.playerService.playersListChange.toRx().subscribe(this.playerListChange); where playerListChange -> playerListChange(player: Player) : void { console.log(player); } – Vince Oct 11 '15 at 23:44
  • I think I answered the same question over [here](http://stackoverflow.com/questions/33063434/this-myservice-myevent-torx-subscribe-called-but-no-dom-refresh-zone-trigge) – Eric Martinez Oct 11 '15 at 23:47

0 Answers0