0

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:

  • in the header component constructor with subscribe and it passes the returned value to a variable

  • In the router guard with first() in canActivate. The example project works as expected.

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.

Ben Taliadoros
  • 7,003
  • 15
  • 60
  • 97
Quwax
  • 1
  • 1

1 Answers1

0

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();
}
karser
  • 1,625
  • 2
  • 20
  • 24
  • 2
    I know that ;-) When I return the observable, the router stops working. My basic question is, how can it happen that I get an empty object returned, althoug it looks like the right observable in the debugger (source is the subject), `. subscribe` is not invoked. The variable I set in the toolbar always gets correctly updated. – Quwax May 16 '17 at 03:23