0

I have the following can activate route guard class

import {OnDestroy } from '@angular/core';
import {
  CanActivate,
  ActivatedRouteSnapshot,
  RouterStateSnapshot,
  Router
} from '@angular/router';
import {Injectable} from '@angular/core';
import {UserAuthorizationService} from "../userauthorizationservice/userauthorizationservice";


@Injectable()
export class ClientSuitsUserGuard implements CanActivate, OnDestroy{
  constructor(private userservice: UserAuthorizationService, private router: Router){}
  userservicesubscription;
  user ={
    id: null,
    isclient: false,
    issuitsviewer: false,
    issuitsadministrator: false,
    issuitssuperuser: false,
    isvenueuser: false

  };

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

    this.userservicesubscription = this.userservice.receiveuser()
      .subscribe(
        (req: any)=>{
          if(req != null){
            this.user = req;
            if(this.user.isclient || this.user.issuitsviewer || this.user.issuitssuperuser || this.user.issuitsadministrator){
              return true;
            }
            if(this.user == null ){
              this.router.navigate(['/signin']);
              return false;
            }else{
              this.router.navigate(['/401']);
              return false;
            }
          }
          this.router.navigate(['/signin']);
          return false;
        }
      );
  }

  ngOnDestroy(){
    this.userservicesubscription.unsubscribe();
  }
}

And I keep getting the error:

ERROR in /home/rickus/Documents/softwareProjects/211hospitality/suitsandtables/frontend/suitsandtables/src/app/services/userservice/authguardservices/isclientuserguard.ts (31,44): A function whose declared type is neither 'void' nor 'any' must return a value.

I want the route guard to receive the user permission check if attributes are true or not and redirect to pages depending on if conditions are false or true.

I feel like my code is correct and this is an interface issue. Is there any quick tweeks I can do to satisfy the interface?

What am I doing wrong?

I have made the following edits based on the answer below but I am now having to deal with a new error because of it.

canActivate(route: ActivatedRouteSnapshot,
              state: RouterStateSnapshot): Observable<boolean>{

    return this.userservicesubscription = this.userservice.receiveuser()
      .map(
        (req: any)=>{
          if(req != null){
            this.user = req;
            if(this.user.isclient || this.user.issuitsviewer || this.user.issuitssuperuser || this.user.issuitsadministrator){
              return true;
            }
            if(this.user == null ){
              this.router.navigate(['/signin']);
              return false;
            }else{
              this.router.navigate(['/401']);
              return false;
            }
          }
          this.router.navigate(['/signin']);
          return false;
        }
      );
  }

with the new error at run time:

ERROR Error: Uncaught (in promise): TypeError: this.userservice.receiveuser(...).map is not a function
TypeError: this.userservice.receiveuser(...).map is not a function
  • Your return statements in the `subscribe` method is not returning values for your `canActivate` method. Instead of subscribing, you'll want to use the `map` method and return that observable chain (updating the return result to be an `Observable`). – Daniel W Strimpel May 09 '18 at 23:24
  • @DanielWStrimpel Any ideas on how to fix? I am not really sure how to move forward with this. –  May 09 '18 at 23:27
  • @DanielWStrimpel can you please code an answer below? So I can give you the points and fully understand what you are saying please –  May 09 '18 at 23:28

1 Answers1

0

As stated in my comment above:

Your return statements in the subscribe method is not returning values for your canActivate method. Instead of subscribing, you'll want to use the map method and return that observable chain (updating the return result to be an Observable).

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
  return this.userservice.receiveuser().map(
    (req: any)=>{
      if(req != null){
        this.user = req;
        if(this.user.isclient || this.user.issuitsviewer || this.user.issuitssuperuser || this.user.issuitsadministrator){
          return true;
        }
        if(this.user == null ){
          this.router.navigate(['/signin']);
          return false;
        }else{
          this.router.navigate(['/401']);
          return false;
        }
      }
      this.router.navigate(['/signin']);
      return false;
    }
  );
}
Daniel W Strimpel
  • 8,190
  • 2
  • 28
  • 38
  • ok so the map allows for the observable to change its scope into the scope of the function rather than the subscription. Correct? That makes sense! –  May 09 '18 at 23:35
  • I now have a new issue `A function whose declared type is neither 'void' nor 'any' must return a value.` this is most likely because I am not doing the second part of your answer. I am not sure how I would turn the map into an observable. Can you finish illustrating your answer? –  May 09 '18 at 23:49
  • I think you are missing some return paths in your mail method (for example if `req == null`). – Daniel W Strimpel May 10 '18 at 00:07
  • lets see ill check –  May 10 '18 at 00:08
  • The map method is mapping the response from your `receiveUser()` call to a boolean value. It will return an observable. – Daniel W Strimpel May 10 '18 at 00:09
  • nope it looks like they are all properly returned. I attempted to subscribe to the map but that didnt work either –  May 10 '18 at 00:10
  • so I should be returning an observable of type boolean then not just boolean? I am going to give that a try –  May 10 '18 at 00:11
  • Yeah don't subscribe. You don't want that. Are you returning the map result as shown? – Daniel W Strimpel May 10 '18 at 00:11
  • I was not! I just did the return lets see now! –  May 10 '18 at 00:14
  • so i have edited your answer to include changes I ment to edit my question. I am doing that now. made a mistake but the point is, I am having a run time error now when I attempt to access the protected url –  May 10 '18 at 00:24
  • You will need to import the observable operator. `import 'rxjs/add/operator/map';` – Daniel W Strimpel May 10 '18 at 00:43
  • isn't that this? import {Observable} from 'rxjs/Observable'; Unless I need to import map? is that what you mean? –  May 10 '18 at 00:46
  • ok imported the thing you asked me to do and it worked. my logic it seems is still off. Checking it out –  May 10 '18 at 00:53
  • Importing observable the way you have it just imports the observable without the operators. You have to individually import them – Daniel W Strimpel May 10 '18 at 00:54
  • oh ok i get it !! –  May 10 '18 at 00:55