Angular 2 equivalent to $broadcast, $emit, $on pub-sub?

5,391 views
Skip to first unread message

Ben McFerren

unread,
Nov 2, 2015, 2:06:05 PM11/2/15
to AngularJS
Can you please point me to a tutorial that outlines the recommended pub-sub practice/syntax for Angular 2 apps?

Thank you greatly in advance for your help

Eric Martinez

unread,
Nov 2, 2015, 5:33:00 PM11/2/15
to AngularJS
Ben,

to communicate between components/directives ng2 provides a class named EventEmitter, which is a subclass of a Subject (see RxJS). I have an example I did for another user, but I'm pretty sure you'll get the idea (if not just ask :D ), see it here http://plnkr.co/edit/MT3xOB?p=info

Ben McFerren

unread,
Nov 2, 2015, 5:47:48 PM11/2/15
to AngularJS
thnx Eric - your plnkr is very helpful

Is this just a parent component / child component relationship or can a component subscribe to messages sent from a service?

Eric Martinez

unread,
Nov 2, 2015, 7:13:42 PM11/2/15
to AngularJS
Ben,

you can subscribe from a service. Note that in this example I created a simple service (just a class) and I pass it through bootstrap, with this the instance is the same one for every component in the application. Also note that I have two siblings components subscribe to the service that get the same content when you press the send data button.


I hope it helps :D

Ben McFerren

unread,
Nov 3, 2015, 6:54:42 PM11/3/15
to AngularJS
Thank you for your guidance Eric. I am still a bit confused though.

To my understanding, the .toRx().subscribe( ... ) function is meant to RECEIVE messages and the .next() function is meant to BROADCAST messages

In this plnkr ( http://plnkr.co/edit/MT3xOB?p=info ) , you invoke the .toRx().subscribe( ... ) function from a data object that seems to be defined/derived originally from the template:

@Component({
  selector : 'child-cmp',
  template : '',
  inputs : ['data']
})
class ChildCmp {
  afterViewInit() {
    this.data.toRx().subscribe((data) => {
      console.log('New data has arrived!', data);
    });
  }
}

In this plnkr ( http://plnkr.co/edit/rNdInA?p=preview ) , you invoke the .toRx().subscribe( ... ) function from an evt object and its emitter function (originating from Service injected into the component's constructor)

@Component({
  selector : 'parent-cmp',
  template : ''
})
class ParentCmp {
  constructor(evt: EventService) {
    evt.emitter.subscribe((data) => 
      console.log("I'm the parent cmp and I got this data", data));
  }
}

Is is possible for the BROADCAST to take place in a function of the Service itself while at the same time, is it possible for the Component to RECEIVE the message without relying upon a returned Service object or Template data object to chain its .toRX().subscribe( ... ) function invokation?

import {Injectable, EventEmitter} from 'angular2/angular2';
@Injectable()
export class DataService {
    items:Array<any>;
    dispatcher: EventEmitter = new EventEmitter();
    constructor() {
        this.items = [
            { name: 'AAAA' },
            { name: 'BBBB' },
            { name: 'CCCC' }
        ];
    }
    getItems() {
        return this.items;
    }
    sendItems() {
        this.dispatcher.next( this.items );
    } 
}
export var DATA_BINDINGS: Array<any> = [
    DataService
];



@Component({
    selector: 'rabble'
})
@View({
    ...
})
export class Rabble {
 
    items       : Array<any>;
 
    constructor( public dataService  : DataService) { 
 
        console.log('this.routeParam', this.dataService.getItems());
    }
 
    afterViewInit() {
        this.data.toRx().subscribe((data) => {
            console.log('New data has arrived!', data);
        });
    }
 
    handleClick() {
        this.dataService.sendItems();
    }
}


Also, what is the correct EventEmitter syntax to use to subscribe to a particular "channel" as we did in angular 1 $Broadcast and $on?

$scope.$broadcast('myCustomEvent', {
  someProp: 'Sending you an Object!' // send whatever you want
});
$scope.$on('myCustomEvent', function (event, data) {
  console.log(data); // 'Data to send'
});


Eric Martinez

unread,
Nov 3, 2015, 8:04:50 PM11/3/15
to AngularJS
Is is possible for the BROADCAST to take place in a function of the Service itself while at the same time, is it possible for the Component to RECEIVE the message without relying upon a returned Service object or Template data object to chain its .toRX().subscribe( ... ) function invokation?


I don't think there's a way to do it like you did in angular1, I barely used it but I remember using broadcast/emit/on. 

The application somehow needs to know about the service and it does by being injected, using Observables is not like using Events (they are not the same). The Service has to be injected so it is instantiated and start working. Note that angular2 runs on its own zone (context) and what you are asking is basically run the service out of it and the notify angular2 of any change in it. I don't think that's a good idea and I couldn't give you a good technical answer. For that I could advise you to stick to angular2's context and run everything on it.

Also, what is the correct EventEmitter syntax to use to subscribe to a particular "channel" as we did in angular 1 $Broadcast and $on?

As far as I know you can not name an Observable, by that I mean there's no way to do 

emitter = new EventEmitter('myCustomEvent');
emitter
.subscribeTo('myCustomEvent', (data) => ...)

That's not possible. Your "channel" is the variable itself, in this case "emitter". If you want another "channel" just create another variable. Another possible way to "name it" would be using objects. I do something like this in one of my testing projects

emitter = {};
emitter
['someName'] = new EventEmitter();
emitter
['someName'].subscribe((data) => ...);
emitter
['someName'].next('send this data');

I hope I was clear enough and at least a little bit helpful since your last questions were more complex :P

PS : Don't take my answers as definitive answers. My knowledge is pretty basic and I answer according to what I know (obviously, d'oh), so you can keep investigating to look for a better way/answer. 

Anil Singh

unread,
Feb 3, 2016, 6:16:08 AM2/3/16
to AngularJS
Good news! for Angular lovers :) Integration of Angular 1 and Angular 2 https://lnkd.in/eRfM7ur
What are major changes in Angular 2? https://lnkd.in/dRqrDa4
AngularJs login HTTP authentication and authorization https://lnkd.in/eJxrT5v

Thank you!
Reply all
Reply to author
Forward
0 new messages