angulartypescriptionic-frameworkobservableionic4

Angular Auth Guard with Subscribe


I have an auth guard and need to run an api call to see if they have access. I don't believe it's possible to return data from a subscribe but how else would I do this?

I need to get the userid and then call the api and then return either true of false depending on the api call.

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from 'src/app/services/auth.service';

@Injectable({
  providedIn: 'root'
})
export class TeamcheckGuard implements CanActivate {
  success: boolean;

  constructor(
    private router: Router,
    private authService: AuthService
  ) {}

  // Checks to see if they are on a team for the current game they selected.
  canActivate(next: ActivatedRouteSnapshot,state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
      this.authService.getUserId().then(() => {
        let params = {
          gameId: next.params.id,
          userId: this.authService.userId
       };

        this.authService.getApi('api/team_check', params).subscribe(
          data => {
            if (data !== 1) {
              console.log('fail');
              // They don't have a team, lets redirect
              this.router.navigateByUrl('/teamlanding/' + next.params.id);
              return false;
            }
          }
        );
      });
    return true;
  }
}

Solution

  • You need to return Observable<boolean> that will resolve to true/false depending on authentication request.

    canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
        return new Observable<boolean>(obs => {
            this.authService.getUserId().then(() => {
                let params = {
                    gameId: next.params.id,
                    userId: this.authService.userId
                };
    
                this.authService.getApi('api/team_check', params).subscribe(
                    data => {
                        if (data !== 1) {
                            console.log('fail');
                            // They don't have a team, lets redirect
                            this.router.navigateByUrl('/teamlanding/' + next.params.id);
                            obs.next(false);
                        }
                        else {
                            obs.next(true);
                        }
                    }
                );
            });
        });
    }