Search code examples
angularangular5observableguardsubscribe

Return a boolean from subscribe in a Guard in Angular 5


I'm trying to return a true in case the subscribe returns me data. Then if error i want it to return me false.

More in deep, my subscribe returns me if theres a cookie or not. If has cookie i want to return me a True and subscribe to another function and if the subscribe goes to error a False.

In case of having cookie it has to subscribe to another function that returns a value. So i have a subscribe inside another, and if both of them returns me a value that i want it has to be TRUE.

Let me show you my code:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {

 this.secureService.config({
    controlType: (this.env.useCookiesFromSTS
        ? SecurityConstant.COOKIE_CONTROL_TYPE
        : SecurityConstant.TOKEN_CONTROL_TYPE
    ),
    advanceTime: this.env.securityConfig_advanceTime,
    isDebug: false,
    isSecure: this.env.securityConfig_isSecure,
    whiteList: ['directline.botframework.com']
  }, {
    urlService: this.env.endpoints_urlSCC,
    urlAttrUser: this.env.endpoints_urlUDS
  },  this.env.appName)
    .subscribe(
      (cookie) => {
        if(cookie){
         this.secureService.getAttrUser(['ComTipoEmpleado'], [''])
         .subscribe(
           //Return true for the guard
           (responseAttrUser) => console.log(responseAttrUser),
           (error) => { console.error(error);
        }

      });
      },
      (err) => {
         return false;
      console.error(err);
    });
}

Basically i need to control if my browser has the cookie and the employee is authorised, if not, then return false.

This is not working:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): 
boolean {

 this.secureService.config({
    controlType: (this.env.useCookiesFromSTS
        ? SecurityConstant.COOKIE_CONTROL_TYPE
        : SecurityConstant.TOKEN_CONTROL_TYPE
    ),
    advanceTime: this.env.securityConfig_advanceTime,
    isDebug: false,
    isSecure: this.env.securityConfig_isSecure,
    whiteList: ['directline.botframework.com']
  }, {
    urlService: this.env.endpoints_urlSCC,
    urlAttrUser: this.env.endpoints_urlUDS
  },  this.env.appName)
    **.map(
      (cookie) => {
        if (cookie){
          return true;
        } else {
          return false;
        }
      });**

 /*this.secureService.getAttrUser(['ComTipoEmpleado'], [''])
    .subscribe(
      (responseAttrUser) => console.log(responseAttrUser),
      (error) => { console.error(error);
      });*/

}

Solution

  • It's look like you are not very familliar with guard / resolver. Guard and resolver will be called by the router. If you guard return a Promise or an Observable the router will wait until those are resolved.

    In you case you are making asynchrone call in your method but you are not returning the promise/obversable, so your guard will only return "undefined" (yes you return false and return true in your call but those will be executed later and noone will take them in concideration).

    Here is a simple way to do what you want using await/async promise (this could have be done with Observable also)

    async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
     try {
     const cookie = await this.secureService.config({
        controlType: (this.env.useCookiesFromSTS
            ? SecurityConstant.COOKIE_CONTROL_TYPE
            : SecurityConstant.TOKEN_CONTROL_TYPE
        ),
        advanceTime: this.env.securityConfig_advanceTime,
        isDebug: false,
        isSecure: this.env.securityConfig_isSecure,
        whiteList: ['directline.botframework.com']
      }, {
        urlService: this.env.endpoints_urlSCC,
        urlAttrUser: this.env.endpoints_urlUDS
      },  this.env.appName).toPromise();
    
      if(cookie){
        const user = await this.secureService.getAttrUser(['ComTipoEmpleado'], ['']).toPromise();
        return user != null;
      }else{
        return false;
      } 
     } catch(err) {
       return false;
     }  
    }