Search code examples
javascriptangularcallbackreturn-valueangular4-router

Angular4 issue with http requests


In my Angular 4 application I am developing an oath guard service. There I want to check if the token is live and if not, user needs to log in again.

Below are the functions I am using to achieve what I want:

isLogedIn(){

    return this.http.get(this.baseUrl+"/check-token?token="+this.currentUser.token).map(res => res.json())
    .subscribe(response => {
          let logedinUser = JSON.parse(localStorage.getItem('currentUser'));
                if(response.message == "_successful" && localStorage.getItem("currentUser") != null){
                    return true;
                }else{
                    return false;
                }
             },err =>{ 
                console.log(err); 
                return false;
           });

}

but the thing is in auth gurd function I cant get the exact out put value of this function. Bellow is my auth gurd function:

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {

    console.log(this.userService.isLogedIn());
    if (this.userService.isLogedIn()) {
      return true;
    } else {
      this.router.navigate(['/login'], {
        queryParams: {
          return: state.url // curent url as a parameter to the login page
        }
      });
      return false;
    }
  }

When I use console.log(this.userService.isLogedIn()); it prints the Subscriber object not the return value. How do I return the value from isLogedIn() function?


Solution

  • Because you're returning a subscription indeed. `

    • this.http.get(...) is an Observable;
    • this.http.get(...).map(...) is an Observable;
    • this.http.get(...).map(...).subscribe(...) is a Subscription;

    The subscribe method returns a Subscription, not the return something that is inside subscribe routine.

    What do I suggest you: return the observable itself in the guard (canActivate accepts Observable<boolean> as return). Do not call subscribe at isLogedIn():

    isLogedIn(): Observable<boolean>{
    
    return this.http.get(this.baseUrl+"/check-token?token="+this.currentUser.token).map(res => res.json())
    .map(response => {
          let logedinUser = JSON.parse(localStorage.getItem('currentUser'));
                if(response.message == "_successful" && localStorage.getItem("currentUser") != null){
                    return true;
                }else{
                    return false;
                }
             });
    }
    

    Note I call map twice: the last one is to manipulate your response to return a boolean. Finally, at canActivate:

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    
      return this.userService.isLogedIn().do(response => {
        if (!response) {
          this.router.navigate(['/login'], {
            queryParams: {
              return: state.url // curent url as a parameter to the login page
            }
          });
        }
      })
    }
    

    I insert the operator do, which is an independent callback, to manage your routing.