Search code examples
angularhttpclientngrx-store

Angular, store-select with http get


i would like to guard a route and do the following:

  • check if user is in ngrx-store
  • if user is in store return true at canActivate
  • if not make an http-get and receicve user
  • if user gets back, store it in store and return true on canActivate
  • if 401, return false

Here is what i got so far:

@Injectable({providedIn: 'root'})
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router, private store: Store<AppState>) {
  }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.store.select(selectUser).pipe(
      take(1),
      map(user => {
        if (!!user) {
          return true;
        }

        return this.authService.getUser$()
          .pipe(
            map(user => {
              this.store.dispatch(addUser({user: user}));
              return true;
            })
          )
      })
    );

  }
}

Error:

Type 'Observable<true | Observable<boolean>>' is not assignable to type 'boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree>'.

Problem is that return this.authService... returns an Observable which results in Observable<Observable>.

How can i untie this knot?


Solution

  •         if (!!user) {
              return true; // Returns a boolean - OK
            }
    
            return this.authService.getUser$()
              .pipe(
                map(user => {
                  this.store.dispatch(addUser({user: user}));
                  return true; // Returns an observable of a boolean - Not OK
                })
              )
    

    Replace with switchMap :

        return this.store.select(selectUser).pipe(
          first(),
          switchMap(user => {
            if (!!user) {
              return of(true);
            }
    
            return this.authService.getUser$()
              .pipe(
                map(user => {
                  this.store.dispatch(addUser({user: user}));
                  return true;
                })
              )
          })
        );