I've got a service that I use to share data between 2 components. That part works flawlessly, but now I need to call a method of component A, when something triggers on the service (and pass a value to that component). How can I do this? I read on older questions that this is a wrong approach but since Im a noob I dont know what to search for a solution. Do I need to use observables?
-
_"Do I need to use observables?"_ - yes. Your service will hold an observable. Your component grabs a reference to this observable and subscribes to it. When that trigger happens, your service will "push" the data into the observable. Anything subscribed to that observable (in this case your component) will get the data. – Joseph Sep 30 '19 at 19:31
-
Thank you very much for your answer. I just need to figure out the syntax now! – dizzydizzy Sep 30 '19 at 19:34
-
Adding to @Joseph's comment, you can use a _BehaviorSubject_ (a sub-type of observable). Refer this [answer](https://stackoverflow.com/a/44414443/2924577) for info on doing that. If the two components have _parent-child_ relationship, then consider using bindings. More info in this [answer](https://stackoverflow.com/a/57813231/2924577). – Nikhil Sep 30 '19 at 19:43
2 Answers
Observables
/ Subjects
are one way. You would have one Subject
in the service, and would use .next(value)
on it to exchange values. Each component which is interested in the value may subscribe to that subject.
Example: (taken from RxJS docs
//your Service
import { Subject } from 'rxjs';
const subject = new Subject<number>();
//Component A (and others as well)
service.subject.subscribe({
next: (num) => console.log(num)
});
//this should work as well with prettier syntax:
service.subject.subscribe(sum =>
console.log(num)
);
//Component B
service.subject.next(7) //passing number 7 to Component A
Whenever you create a subscription, make sure to always unsubscribe! Else you might end up with stacks of subscriptions, which will all get triggered simultaneously in the very same component.
From personal experience, I found it more helpful to outsource any functions and variables that could be considered as global into a dedicated service, if possible. If you directly read the variables of a service from your components (and modify them if necessary), you'll have the same effect. That works as long as you keep a proper service structure. Some examples of dedicated services with global use are:
- Translations (
TranslationService
) - Rights Management (
PermissionService
)

- 562
- 4
- 18
-
In your example would I be able to send the value on service.subject.next(VALUE) to the service, and then to the suscribed components? – dizzydizzy Sep 30 '19 at 19:58
-
Exactly, the Subscription is the event handler which gets triggered. As I work with Angular often; I avoid Subjects and Observables because you quickly loose overview. Another issue is that Subscriptions are not singleton, and each instance exists until you unsubscribe... (`subscription.unsubscribe()`)...that caused me quite some issues with duplicate handling of events. – gekkedev Sep 30 '19 at 20:01
I think Joseph's idea is the way to go.
Here's how I'd implement it:
class FooService {
private _newEvents = new Subject();
newEvents$ = this._newEvents.asObservable();
addNewEvent (ev) {
this._newEvents.next(e);
}
}
// Allow `A` class to communicate with `B` class
class A {
addEvent (ev) {
this.fooService.addNewEvent(ev);
}
}
class B {
private subscription: Subscription;
ngOnInit () {
this.subscription = this.fooService.newEvents$
.subscribe(e => {})
}
ngOnDestroy () {
this.subscription.unsubscribe();
}
}
Note that if your B
class subscribes to multiple observables, you should unsubscribe from them using, among other solutions, takeUntil.

- 11,116
- 1
- 14
- 31