1

I have auth guard service

 constructor(private _auth: AuthService, private _router: Router) { }

  canActivate() {
    if(this._auth.isLoggedIn()){
      return true;
    } else {
      this._router.navigate(['/login']);
      return false;
    }
  }

and that's my isloggedin method

isLoggedIn(): boolean {
  return this._session.sessionId.length > 0;
}

and login

login(user: User): any {
 return this._http.post(this.authUrl, user)
   .subscribe(x => {
     this._session.sessionId = x.sessionId;
     this._session.name = x.username;
   });
}

my problem is that after login it first check's isloggedin and I think it's because of subscribe (login method waits response from server)

so I added asObservable.first() in isLoggedIn

isLoggedIn(): boolean {
  return (this._session.sessionId.length > 0).asObservable().first();
}

but it logs in console that

Property 'asObservable' does not exist on type 'boolean'.

How can I solve that?

gsiradze
  • 4,583
  • 15
  • 64
  • 111

1 Answers1

0

If you subscribe() then the call returns a Subscription not an Observable

It's not clear from your question what login() is supposed to do exactly but because you return the result of the _http.post() call I suspect you actually want to return an Observable. For this you need to change subscribe to map (map needs to be imported):

login(user: User): any {
 return this._http.post(this.authUrl, user)
   .map(x => {
     this._session.sessionId = x.sessionId;
     this._session.name = x.username;
   });
}

update

constructor(private _auth: AuthService, private _router: Router) { }

loggedIn = new Subject();

login(user: User): any {
 return this._http.post(this.authUrl, user)
   .map(x => {
     this._session.sessionId = x.sessionId;
     this._session.name = x.username;
     this.loggedIn.next(true);
   });
}

canActivate() {
  return loggedIn.map(loggedIn => {
    if(this._auth.isLoggedIn()){
      return true;
    } else {
      this._router.navigate(['/login']);
      return false;
    }
  });
}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • I'm posting data to the server and it returns me `sessionId` and `username` that's why I'm subscribing to that – gsiradze Feb 11 '17 at 13:37
  • Then `return` seems redundant. – Günter Zöchbauer Feb 11 '17 at 13:37
  • anyway with or without return it first goes to isloggedin and then to login. When I click to login button second time then returns isloggedin true (but it's second call to server and `sessionId` is not the same) – gsiradze Feb 11 '17 at 13:40
  • I updated my answer. If some of the methods are within the service (for example `_auth` - wasn't exactly sure from the code in your question), then just prefix the call with `this._auth` and move the subject to the service) – Günter Zöchbauer Feb 11 '17 at 13:43
  • Glad to hear. Thanks for the feedback :) – Günter Zöchbauer Feb 11 '17 at 13:58
  • can you help me in one more thing? this code works and guard waits subscribtion to finish but after that auth guard not working – gsiradze Feb 11 '17 at 14:48
  • Perhaps you need `first()` like shown in http://stackoverflow.com/questions/38425461/angular2-canactivate-calling-async-function/38425489#38425489 – Günter Zöchbauer Feb 11 '17 at 14:51
  • I added that and it navigates for the first time but then when I want to navigate using `routerLink` it isn't going inside return statement – gsiradze Feb 11 '17 at 14:58
  • Hard to tell. Perhaps something like https://github.com/angular/angular/issues/10014 – Günter Zöchbauer Feb 11 '17 at 15:02
  • what's difference between subscription and observable? when I write map instead of subscribe i'm not getting values – gsiradze Feb 11 '17 at 16:10
  • 1
    A `Subscription` allows you to cancel the subscription, but doesn't allow you to apply any operators. If you pass a `Subscription` the receiver can't subscribe and has no way of getting values from. If the receiver needs to subscribe, you need to pass an `Observable` instead, this is also what the router expects to receive from the guard. – Günter Zöchbauer Feb 11 '17 at 16:14