Search code examples
angularguard

I am trying to receive a boolean value from a service in Angular but it only return the whole object


I'm building a simple service that returns if I'm part of a team or not (a simple true or false). I already validated the backend and it works. The missing part is in my angular app.

The authentication.service.ts looks like

import { Injectable } from '@angular/core';

import { Http, Headers, Response, Request, RequestMethod, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { environment } from '../../../environments/environment';

let roleUrl = environment.apiBaseUrl + 'CoreRole';
let options = new RequestOptions({ withCredentials: true });

@Injectable()
export class AuthenticationService {

  constructor(private http: Http) { }

  getRoleByName(name): Observable<boolean> {
    console.log('getRoleByName FN: ' + roleUrl + '?name=' + name);
      return this.http.get(roleUrl + '?name=' + name, options)
      .take(1)
      .map(res => <boolean>res.json())
      .catch(this.handleError);
  }

  private handleError(error: Response) {
    console.log(error);
    return Observable.throw(error.json().error || 'Server error');
  }  

}

And the or.guard.ts looks like

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Router } from '@angular/router';

import { Observable } from 'rxjs/Rx';
import { AuthenticationService } from '../services/authentication.service';

@Injectable()
export class OrGuard implements CanActivate {
  constructor(private authenticationService: AuthenticationService, private router: Router) { }

  isProjectTeam : boolean;

  canActivate() {

    this.isProjectTeam = <boolean><any> this.authenticationService.getRoleByName("ProjectTeam");

    if(this.isProjectTeam === true)
    {
      return true;
    }
    else
    {
      this.router.navigateByUrl('/not-authorized');
    }

    return false;
  }

} 

As result, I'm always taken to /not-authorized page because the isProjectTeam variable never gets formatted to boolean.

Can anyone help me?

Thanks


Solution

  • You are trying to cast an Observable to a boolean, when you want is to grab the result of the Observable.

    If you try let x = this.authenticationService.getRoleByName("ProjectTeam");, you'll see x is of type Observable<boolean>.

    You can have canActivate() return an Observable<boolean> instead of a boolean, so change your code like this:

    canActivate(): Observable<boolean> {
        return this.authenticationService.getRoleByName("ProjectTeam").map(
            response => {
                if (response) {
                    return true;
                }
                else {
                    this.router.navigateByUrl('/not-authorized');
                    return false;
                }
            });
    }
    

    If you're using TypeScript, one thing you can do when messing with complex objects like this is to break it into pieces with code like let x = .... Intellisense should tell you what types you are dealing with, and give you clues why your code isn't compiling like you think it should.

    More info on the CanActivate guard