I have a UserService
which has a getUser
method that returns an observable of type User
class.
The getUser
checks if the user already exists, if so, it returns the user, or else it creates a new user.
When creating a new user, it also does an API call to the 'roles' data for the user, the code looks as follows:
public getUser(): Observable<User> {
if (!UserService.user) {
UserService.user = new User();
return this.getGroups().pipe(
map(response => {
response.value.map(v => this.setRol(v));
return UserService.user;
}));
}
else {
return of(UserService.user);
}
}
But there is a problem.
When I subscribe to this method from two different components, one will follow the path in the first if statement, and the second will return the created user in the else statement.
But the second returns the created user before the first subscription has finished the API call to get the roles (groups) the user belongs to. which gives me errors.
How can I fix this? And what is the best practice to fix this?
shareReplay(1)
RxJS makes a simple form of caching (like this) really easy
private userCache$ = this.getGroups().pipe(
map(({value}) => {
UserService.user = new User();
value.map(v => this.setRol(v));
return UserService.user;
}),
shareReplay(1)
);
public getUser(): Observable<User> {
return userCache$;
}
Now this.getGroups()
is only ever called the first time userCache$
is subscribed to. After that, every other call waits for the API call to finish and/or gets the cached result of that call.