Angular app - User login, logout and session reload with Observables

给你一囗甜甜゛ 提交于 2021-01-29 07:10:58

问题


This is a followup question for another question I had posted, which remains half-solved: RxJS shareReplay() does not emit updated value

I am creating an Angular app and I'm trying to use Observables extensively. The problem is with creating a UserService class which has an observable user$ which can be piped to throughout the application to get the currently logged in user.

The currently accepted answer (by @DeborahK - she had been very patient with me) is a great solution, but has a bug - A user logs in, then logs out. Then a second user logs in. The user$ object for the second user is not refreshed (because it is shareReplay()) and they can see all the data of the first user.

If I refresh the page, things work just fine.

I found another question with a similar problem from 2018 and it still remains unsolved: Angular 2 Typescript reload components on login/logout

I have tried several other ways, even with BehaviorSubject, but the problem there is that the user$ is never ready in time for the CanActivate auth-guards. So, the auth-guards get the value of the user as null and redirect them to the login page.

I am looking for a way to serve the following use cases:

  1. User should be able to login
  2. Show 'Logout' link (and/or other user related things) when the user is logged in.
  3. Refreshing the page should load the user for the auth-guards, in order to redirect to the right page.
  4. User should be able to logout
  5. New user should be able to login
  6. user$ could be used several times and still call the webservice only once throughout its lifetime.

In one of the solutions (stackblitz example here), it appears that things are working fine, until you pop the hood to check the Network tab of the browser. Each time $user is used, a new network call is made. One of my pages has an array of data being looped through. With this approach, there are so many network calls made to the API, that the browser become irresponsive.

Even with the simplest of examples...

user$ = this.logInAction$.pipe(
    switchMap(userId => {
      console.log("userid = ", userId);
      if (userId > 0) {
        // returning webservice observable
        return this.callWS(userId);
      } else {
        // user logged out
        return of(null);
      }
    }),
  );

... a stream (or the observable) once returned is what is subscribed to. There is no way to actually switch the observable again when required.

Is there a way to achieve the desired result using RxJS and Observables?

来源:https://stackoverflow.com/questions/63061257/angular-app-user-login-logout-and-session-reload-with-observables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!