Angular2 + RxJS BehaviorSubject subscription not working on all components
Asked Answered
C

4

5

I'm trying to make some sort of communication between my components, so I'm using a service with a BehaviorSubject and Subscription in the components like this:

Service (code related to the problem):

import { BehaviorSubject } from 'rxjs/BehaviorSubject'

private _clientModalActionSource = new BehaviorSubject<string>('')
modalAction$ = this._clientModalActionSource.asObservable()
public updateClientModalAction(action) {
   this._clientModalActionSource.next(action)
   console.log('sent')
}

Component A :

this._api.updateClientModalAction(id)

Component B :

import { Subscription } from 'rxjs/subscription'

private _subscription: Subscription
ngOnInit() { this._subscription = this._api.modalAction$.subscribe(res => {
   this.refreshModal(res)
   console.log('received')
})}

This is working perfectly if Component B is child of Component A, but if A is the root component and B is inside its <router-outlet> (or the opposite) nothing is being received to the subscription, I only get sent in the console.

what am I doing wrong?

Continuance answered 14/9, 2016 at 19:53 Comment(0)
C
36

well the problem was simpler than I thought, I was not using the service on a higher level, I shouldn't have used providers: [ApiService] in each component, instead it should be only on the higher root component.

I hope this will help someone.

https://github.com/angular/angular/issues/11618#event-790191142

Continuance answered 15/9, 2016 at 5:41 Comment(3)
Thanks a ton, bro ! – Inhalator
Do we still need to do this if in the service its mentioned as @Injectable({providedIn: 'root'}) ? plz help! – Fosque
It's strange, cause angular doesnt give any error so if i didnt read this question i couldnt found solution πŸ€¦πŸ»β€β™‚οΈ – Burdened
A
2

if you are going to share things between components.

  1. You should have to use that apiService in the high-level module. like : providers: [ApiService].
  2. You should have to be in the component to catch the subscription of rxjs in the component.
Alden answered 24/1, 2020 at 6:26 Comment(0)
C
1

besides of your answer you have to use

@Injectable({
providedIn: 'root'})

in order to load the service on the root.

Cystitis answered 28/8, 2020 at 13:42 Comment(0)
B
0

In my case subscription didn't happen because of a silent error in the inner function:

  ngOnInit(): void {
    this.infoService.entries.asObservable().subscribe(
      entries => {
        this.entryBody = entries[0].body;
      });
  }

As soon as I wrapped this line with a check it started to work:

if (entries.length > 0) {
  this.entryBody = entries[0].body;
}

So to clarify: there were no error messages in the console for failing array index.

Befuddle answered 24/7, 2021 at 17:52 Comment(1)
It will fail if entries is undefined or null. Check will be if (entries && entries.length > 0) – Demagogue

© 2022 - 2024 β€” McMap. All rights reserved.