Broadcast event in Angular 6 / Typescript
10,936
you can use Subject
export class EventService<T> {
protected _eventSubject = new Subject();
public events = this._eventSubject.asObservable();
dispathEvent(event) {
this._eventSubject.next(event);
}
}
Related videos on Youtube
Author by
Jimmyt1988
Updated on June 04, 2022Comments
-
Jimmyt1988 almost 2 years
I have the following structure:
<app> <test-a></test-a> <test-b></test-b> </app> @Component({ selector: 'app', templateUrl: './app.component.html', }) export class AppComponent { } @Component({ selector: 'test-a', templateUrl: './testa.component.html', }) export class TestAComponent { } @Component({ selector: 'test-b', templateUrl: './testb.component.html', }) export class TestBComponent { }
Test B
contains selectable items. When one is selected, i'd like to tell Test A that the item was selected...I think there are 2 options i'm aware of that can achieve this.
- Use
App
to store the selected item. Modify that selected item inTest B
and then allowTest A
to react... but it makes an ugly tight coupling between theTest A
andTest B
components... and the parentApp
component. I don't like that idea. - To create some kind of "Event Subscriber" service that stores an array of various Observables which can be subscribed against. My current implementation here (not finished):
// Model required for my own class
export class KeyValuePair<T> { public key: string; public value: T; construct(key: string, value: T) { this.key = key; this.value = value; } }
// How my implementation might look (wip)
import { Observable, of } from "rxjs"; import { KeyValuePair } from "../models/keyvaluepair"; import { Injectable } from "@angular/core"; @Injectable({ providedIn: 'root', }) export class EventService<T> { protected subscriptions: KeyValuePair<Observable<T>>[]; public Broadcast(key: string, value: any) { var observable = new Observable<T>(); observable.subscribe((a) => { return of(value); }); this.subscriptions.push( new KeyValuePair<Observable<T>>( key, observable ) ); } public Subscribe(key: string): Observable<T> { var observable = this.subscriptions.find((sub) => { return sub.key == key; }); return observable.value; } }
// How you might create a event
this.testEventService.Broadcast("itemSelected", item);
// How it might be used
this.testEventService.Subscribe("itemSelected").subscribe((item) => { this.changeItem(item); });
However, surely i shouldn't have to write this stuff..? In angularjs and jquery there was a $broadcast and $on kind of thing that made life so simple... what am i missing here? Is there an easier way in angular 6 and typescript?
Edit:
I have made a service people can use, please tell me if it sucks: https://jsfiddle.net/jimmyt1988/oy7ud8L3/
-
izmaylovdev almost 6 yearsI think that you can make it easier, I can help if you interested.
- Use
-
izmaylovdev almost 6 yearsand you can use
eventService.events.subscribe(event => {...})
andeventsService.dispatchEvent(event)
-
Jimmyt1988 almost 6 yearswhat would event look like in this case?
-
Jimmyt1988 almost 6 yearsOh, i see, this is just a one use kind of thing? how do i assign a key to it? so i can store different events which have different data?
-
izmaylovdev almost 6 yearswhatever you want, in your case you can use something like redux Action -
{ action: 'itemSelected', payload: {} }
-
izmaylovdev almost 6 yearsyou also can create difference selectors from this subject
public itemSelectedEvents = this.events.pipe( filter(e => e.action === 'itemSelected'), map(e => e.payload) )
-
izmaylovdev almost 6 years"so i can store different events which have different data?" - Yes, you can.
-
Jimmyt1988 almost 6 yearsThanks for the help. i'll give this a whirl when I get back from work and give you a tick when I get it to work. thanks man!
-
Jimmyt1988 almost 6 yearsThanks, i read up on Subjects too. perfect choice for the job. Odd there is no premade service for this. had to create the entire thing myself :(
-
Jimmyt1988 almost 6 yearsI've added my final service implementation to the OP. Thanks for your help.
-
izmaylovdev almost 6 yearshere my implementation for that service jsfiddle.net/izmaylovdev/3ybxwuas/13
-
Jimmyt1988 almost 6 yearsOh i see, a subject can have multiple objects in it. Good to know! Thanks. Thank you so much man!