I'm trying to implement user permissions in an Angular app, but to put it simple, this is the scenario:
Upon loading a MainModule
, I make an HTTP request and store the data in the localStorage
, so the next time I can retrieve the data from there. This logic is inside an Observable
, to which I'm subscribing from several places.
The problem is, if two subscriptions are executed at the same time, two HTTP request will be made before I even have the chance to store the data in the localStorage.
That's it, but to explain it further...
I'd like to make the HTTP request only once, store the data in the localStorage and emit the value, and from the second subscriber onwards, ignore all this logic if possible and just return the last emitted value.
I tried to use a BehaviorSubject
, but then I get the last emitted data when I re-enter the module (i.e. user_A logs out and user_B logs in). The Service I'm using is provided in root
, I couldn't provide it in MainModule
because I get DI errors in some guards I have there. I also read about the share
operator, but I'm not really sure about how to use it.
CodePudding user response:
Use share() operator to share source among multiple subscribers. This will make sure the response is shared among the many subscribers and prevent duplicate HTTP request.
getSomeData(): Observable<any> {
return this.http.get<any>('/endpoint').pipe(share());
}
You could do an if condition before calling getSomeData()
to check if the data is already available in the store.
CodePudding user response:
I'm not sure is this is practical, but I like to share. first you need 1 more subject
loggingIn: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(null);
Then inside login()
service just trigger status like
login(): void {
this.loggingIn.next(true);
// ....loging
this.loggingIn.next(false);
}
So getUser()
go to be look like this
getUser(): Observable<User> {
return this.loggingIn.pipe(() => {
return this.user.pipe(filter(user => user !== null));
});
}