sobczi
sobczi

Reputation: 131

Easiest way to convert await/async function to work with observables

As far as I understand I shouldn't really use async/await methods in Angular.

So I'm trying to figure out how to get it going without those methods.

I'm using canActivate function which first of all calls AuthService which asks PHP if current JWT token is valid. However, at the current moment I accomplished this only by doing so:

canActivate

async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
  {
    var valid_token: boolean;
    var role: number;

    await this.auth.validate_token()
    .then(res => 
    {
      valid_token = res['valid_token'],
      role = res['role']
    });

    //define if current user can access
  }

validate_token

validate_token()
  {
    return this.http.post(globals.api_url("verify-token.php"), 
      {
        jwt: localStorage.getItem('token')
      }).toPromise()
      .then(result => result)
      .catch(result => result['valid_token'] = false);
  }

And by now I have to call this validate_token() function in some other places and I don't want to set every function for async/await.

I was playing around some with observables but still wihout any proper result.

verify-token.php returns if current token is valid and some other user proporties

Upvotes: 0

Views: 274

Answers (2)

C.OG
C.OG

Reputation: 6529

You wouldn't need to use async/await because the route guards and resolvers will wait for a promise or observable to return before it proceeds.

If all guards return true, navigation will continue. If any guard returns false, navigation will be cancelled

Your observable just needs to return a true or false value.

validate_token

validate_token()
  {
    return this.http.post(globals.api_url("verify-token.php"), 
      {
        jwt: localStorage.getItem('token')
      })
  }

canActivate

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
  {
    var valid_token: boolean;
    var role: number;

    return this.auth.validate_token()
      .pipe(
        tap((res) => {
          valid_token = res['valid_token'],
          role = res['role']
        }),
        map((res) => {
          return res['valid_token']
        }),
      )
  }

Notice that the observable in the canActivate guard returns res['valid_token']

Upvotes: 1

Nouh Belahcen
Nouh Belahcen

Reputation: 854

It's better to use Observable instead of Promise

private authStatusListener = new Subject<boolean>();

constructor(private http: HttpClient) { }

getAuthStatusListener() {
   return this.authStatusListener.asObservable();
}

validate_token()
{
   const user = {email: email, password: password};
   this.http.post<{token: string}>(url, user) .subscribe(response => {
        const token = response.token;
        this.authStatusListener.next(true);
   }, (error: any) => {
        this.authStatusListener.next(false);
   });
 }

and you can subscribe to the Observable from another component and for every success login will fire a true and failure login will fire a false

 this.authService.getAuthStatusListener()
  .subscribe(isAuthenticated =>{
    this.loading = isAuthenticated;
 });

You can see my simple project to understand more link

Upvotes: 0

Related Questions