-1

I am trying to make a persistent login and everything works fine except if I am reload the page from the dashboard which is a page protected of AuthGuard I get redirected to login page but still I am logged in and also navbar works properly.Any suggestions would help me out a lot.

export class AuthGuard implements CanActivate {

    constructor(private auth: AuthService, private router: Router) {

    }

    canActivate(
        next: ActivatedRouteSnapshot,
        state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
        return this.auth.getLoggedIn
            .pipe(
                map((res: boolean) => {
                    console.log(res);  // this one returns false when I reload page    
                    if (!res) {
                        this.router.navigate(['login']);
                        return false;
                    }
                    return true;
                })
            );
    }
}

Below is my auth service

export class AuthService {

    private loggedIn: BehaviorSubject<boolean>;

    constructor(private http: HttpClient) {

        this.loggedIn = new BehaviorSubject<boolean>(false);
    }

    setLoggedIn(value: boolean) {
        this.loggedIn.next(value);
    }

    get getLoggedIn() {
        this.updatelogin().subscribe(res => {
            this.loggedIn.next(res);

        })
        return this.loggedIn.asObservable();
    }

    updatelogin() {
        return this.http.get<boolean>('/api/islogged'); // API server returns a boolean by calling req.isAuthenticated()-passport
    }
}

I deleted unnecessary code but if you need anything more let me know and I will edit my post.

Gabriel Costin
  • 112
  • 3
  • 13

1 Answers1

1

Simply using a Subject instead of a BehaviorSubject should resolve the issue :

You start by creating a BehaviorSubject with a false value

this.loggedIn = new BehaviorSubject<boolean>(false);

Then you make an HTTP call to emit an new value

this.updatelogin().subscribe(res =>{
   this.loggedIn.next(res);
 })

But you don't wait for this call to end to return a value

return this.loggedIn.asObservable();
  • With you code not even my nav bar is working, and btw wasn't me who down vote you answer – Gabriel Costin Sep 13 '18 at 12:22
  • @GabrielCostin not adressed to you don't worry. What happens, do you have any error ? And I can't know what happens to your navbar if you don't post the code of it –  Sep 13 '18 at 12:26
  • @GabrielCostin also, try changing your Behavior subject to a Subject, see how it behaves –  Sep 13 '18 at 12:27
  • Ok I changed to Subject and now seems it is working but I have to read somewhere why – Gabriel Costin Sep 13 '18 at 12:35
  • That's the reason I have explained you : since your BehaviorSubject starts with false, the guard takes the false value because it doesn't wait for the HTTP call to finish. I'm editing my answer with the solution. –  Sep 13 '18 at 12:36
  • 1
    @GabrielCostin the difference between `Subject` and `BehaviorSubject` is that a behavior subject will emit it's first value (here bing false), while the subject will wait for a value to be streamed before returning it. –  Sep 13 '18 at 12:39
  • plus one to balance the minus. this answer is correct. – Stavm Sep 13 '18 at 12:43