Quwax
Quwax

Reputation: 1

Angular and RxJS Subject headache with canActivate

I got an example Angular2 project using firebase. The authService is using a method isAuthentificated with a subject, which returns the subject.asObserveable.

The method is called twice:

I reworte it without the FirebaseAPI with my own stuff and it works as expected in the header component, but in the router guard I always get an empty object back. If I use it the way as in the example project, the router stops working, so I modified it, to see what happens. This is the code from the authService:

  isAuthenticated() {
const state = new Subject<boolean>();
state.subscribe(x => console.log('Subject start: ' + x));
this.localStorageService.observe('myToken')
  .subscribe((newToken: MyToken) => {
    console.log('localStorageCheck: ' + JSON.stringify(newToken));
    if ((newToken !== null) && (newToken.token !== '')) {
      state.next(true);
    } else {
      state.next(false);
    }
    console.log('state changed');
  });
state.subscribe(x => console.log('Subject subscribe: ' + x));
return state.asObservable();

}

and this is the code of th guard:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
let pass: boolean = false;
const val = this.authService.isAuthenticated().first();
val.subscribe((x:boolean) => {
  console.log('Guard says: ' + x);
  pass = x;
});
// return val;
return pass;

}

the example project just has: return this.authService.isAuthenticated().first(); I can't see any difference in the logic and would like to understand, what I'm missing here.

Thank you

ps. the code also working with the guard looks like this:

isAuthenticated() {
const state = new Subject<boolean>();
firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    state.next(true);
  } else {
    state.next(false);
  }
});
return state.asObservable();

}

After some more testing I can observe, that canActivate runs as soon as the subject is updated in my project and this doesn't happen in the example project (although the subject is updated there as well). The only difference is that the Example uses the observer from Firebase and I use the one from ng2-webstorage. I can work around this of course by setting a private var outside canActivate and this works.

I'd really like to understand the reason for this different bahaviour. Hope someone can elighten me, thanks.

Upvotes: 0

Views: 600

Answers (1)

karser
karser

Reputation: 1693

You can return not only boolean but Observable or Promise in canActivate method:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.authService.isUserAuthenticated.isAuthenticated();
}

Upvotes: 0

Related Questions