Angular2 Observable BehaviorSubject service not working
Solution 1
Every time you emit a value, you should create a new object instead of emitting the same mutated object. That will protect you from change detection issues. It'd be better to always assign a new Object to this.keys
when you change it though.
this.data.next([...this.keys]);
You can use asObservable()
here
public getData(): Observable<number[]> {
return this.data.asObservable();
}
Also check for what Günter Zöchbauer said. Are you providing the service as a singleton?
Solution 2
I faced the same issue at some point. It's likely the reason is that your service is not a singleton, i.e. that every subscriber gets a new instance. Contrary to Angular 1, in A2 services are not singletons.
If you want to have one instance of the service shared by multiple services/components, put it in providers
of your parent @Component
or @NgModule
.
@NgModule({
declarations: [],
imports: [],
bootstrap: [AppComponent],
providers: [DataService]
})
export class AppModule {
}
Related videos on Youtube
kjoetools
Updated on June 26, 2022Comments
-
kjoetools almost 2 years
I'm trying to create my own observable service but after i get the initial data from the service, any updates to the service aren't propagated to any subscribers. Service looks like this:
import { Injectable } from '@angular/core'; import { Observable, BehaviorSubject } from 'rxjs/Rx'; @Injectable() export class DataService { keys : number[] = [4,5,1,3,2]; private data :BehaviorSubject<number[]> = new BehaviorSubject(this.keys); constructor() {}; public setKey(i:number, val:number) :void { this.keys[i]=val; this.data.next(this.keys); } public getData() :Observable<number[]> { return new Observable(fn => this.data.subscribe(fn)); } public getKeys() :number[] { return this.keys; } }
the component using the service gets the initial data just fine. that component gets its data in the constructor:
constructor(public dataService: DataService) { dataService.getData().subscribe(data => { console.log("Gotcha!"); this.data.datasets[0].data = data) }); };
which gives one Gotcha in the console log. But after updating the data with setKey(2,3) somewhere else, i was expecting the this.data.next(this.keys); to send data to all subscribers and data would be updated inside that component accordingly. but no data is sent to the subscribers..
i thought i figured the Observables out but please dont be friendly if i'm missing the point here ;) any pointers in the right direction will be greatly appreciated!
-
Günter Zöchbauer over 7 yearsSounds like you are providing the service more than once which leads to different components getting different instances.
-
webmaster over 7 yearsWhat should be the approach when working in modules. I have a similar service. Some of my components (in different modules) subscribe on an observable in my auth service and receive data when it changes but others don't receive data. Eg. when my login (btn) component emits next on the observer the login components sees the change but my header & sidebar components don't while they are also subscribed, I think it has to do with lazy loading or so, or cache, or some parent child problem.. pff
-
jminuscula over 6 years@GünterZöchbauer thanks for this! I was providing the service both as part of the component and in the parent module. It was driving me crazy!
-
Tasos Anesiadis about 5 years@GünterZöchbauer I literally lost hours on this. Thank you so much.
-
BALAJI RAJ almost 4 years@GünterZöchbauer. Thanks a lot. i'm new to Angular, it helped me to fix the issue quickly.
-
-
kjoetools over 7 yearsthat works like a charm! (after i corrected my rookie mistake that Gunter pointed out coughcough*)..
-
kjoetools over 7 yearsi had it in bootstrap but also in the providers inside the components. removing it from made it all work :) tnx! wondering though, i was on RC.4 and had no @NgModule. You're referring to RC.5 probably? when i upgraded i got all kinds of weird traceur messages in the console and it broke my application (following the angular2 site's upgrade path). have you tried their upgrade path and got away with it?
-
Konrad Garus over 7 yearsI only started with RC5, so I am not really familiar with the upgrade path and its quirks. Lucky me, I guess. :-)
-
Emil Rosenius almost 7 yearsAfter almost 4 hours of trying literally every single solution, this finally solved all of my problems. Thank you so much
-
bkdraper about 5 yearsthis one was my solution. 3 years later in 2019 and still not one BehaviourSubject tutorial i went through mentioned anything about the singleton problem or the proper place to set the service provider like Konrad mentions here. Thanks Konrad.
-
Wilt over 4 yearsHow to deal with a long living object that is not supposed to be changed, say a object reflecting a REST resource that mutates over time. Is there some workaround? I want to anyway update my view listening to changes emitted by a
BehaviorSubject
exactly for such a case. -
Kshri almost 4 yearsDo we still need to do this if in the service its mentioned as @Injectable({providedIn: 'root'}) ? plz help!