0

I have 2 services (AuthService & AuthRedirectService)

AuthService uses Http service for get simple data {"status": 4} from the server and return response.json().status <- number

AuthRediredService implements OnActivate and uses AuthService service. This is the only method AuthService.GetStatus() : number, but it returns undefined

AuthService

GetStatus(): number {
    let status: number;
    this.http.get(this.host + "/api/auth/")
    .subscribe((value: Response) => {
      status = value.json().status;
      console.log(value.json().status); // write real number 4
    });
    return status; // 4
  }

AuthRedirectService

  canActivate() : boolean
  {
    console.log(this.auth.GetStatus()); // undefined  !!!!!!!!
    if(this.auth.GetStatus() == StatusCode.Logined)
    {
      // redirect code
      return false;
    }
    return true;
  }
Dmitriy Gavrilenko
  • 300
  • 1
  • 3
  • 18
  • 2
    `http.get` is asynchronous, you will have already returned out of `GetStatus()` before it resolves. – silentsod Dec 02 '16 at 22:27
  • 1
    You can check out Gunter's answer here: http://stackoverflow.com/questions/38425461/angular2-canactivate-calling-async-function for inspiration and a deeper understanding of async canActivate() implementations. – silentsod Dec 02 '16 at 22:56

1 Answers1

0

This is simple Javascript asynchronous problem and it's nothing to do with Angular2.

In javascript , when you call a async method , like a http call that might resolve after 10mintues , you can't expect to have the result right away :

Let's say :

   myAsyncFunction(){
       let theResult;  // First: this line fired
       callAHttpServiceThatTakes1Minute() // Second: we called the function that returns the result in 1 mutine
       .then((res)=>{
          theResult = res; // Forth :  will be available after 1 minute 
       });

       console.log(theResult); // Third : This is undefined because number Forth hasn't finished yet.
   }

To fix your problem though , your route should be something like this :

 { path : 'home' , component : HomePageComponent , resolve : { user : GetStatusResolver } } ,

And then :

@Injectable()
export class GetStatusResolver implements Resolve {
    constructor ( private auth : AuthService ) {
    }

    resolve ( route : ActivatedRouteSnapshot , state : RouterStateSnapshot ) : Observable<User> {
        return  this.auth.GetStatus() ;
    }
}
Milad
  • 27,506
  • 11
  • 76
  • 85