7

I'm using an auth guard in angular 5 to check if the user should be able to navigate to a specific page. I am getting an error related to returning an observable:

A function whose declared type is neither 'void' nor 'any' must return a value.

This is my authguard.ts

import { Injectable } from '@angular/core'; import { Router, CanActivate, ActivatedRoute, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { ApplicationVerificationService } from '../../service/application-verification.service';

@Injectable() export class AppStatusGuard implements CanActivate {

  applicationId: number;   personId: number;

  constructor(
    public router: Router,
    public readonly activeRoute: ActivatedRoute,
    public readonly applicationVerificationService: ApplicationVerificationService) { }

  loginRoute: boolean;   memberRoute: boolean;


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

    this.applicationId = Number(route.params["applicationId"]);
    this.personId = Number(route.params["personId"]);

    // Make sure they are allowed on this page, if not re-direct
    const url = this.applicationVerificationService.getRouteForFellowshipApplicant(this.personId, this.applicationId)
      .subscribe((res: string) => {
        console.log(url);

        if (res !== `application-status/${this.personId}/${this.applicationId}`) {
          console.log("failure");
          // this.router.navigateByUrl(url);
          return false;
        } else {
          console.log("success");
          //this.router.navigateByUrl(url);
          return true;
        }
      });   
  }; 
};

This is my verification service

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';
import 'rxjs/Rx';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class ApplicationVerificationService {
  constructor(
    private readonly httpClient: HttpClient,
    private readonly router: Router) { }

  getRouteForFellowshipApplicant(personId, applicationId): Observable<string> {
    this.httpClient.get('api/application-verification/' + personId).subscribe((responseObject: IFellowshipApplicationStatus) => {

      return Observable.create(observer => {

        if (responseObject.preApplicationVerificationStatus === 'GoToTrackerPage') {
          observer.next('application-status/' + personId + '/' + applicationId);
        }
        if (responseObject.preApplicationVerificationStatus === 'GoToApplicationFormPage') {
          observer.next('application-form/' + personId + '/' + applicationId);
        }
        if (responseObject.preApplicationVerificationStatus === 'GoToContactIceForInfoPage') {
          observer.next('contact-us/' + personId + '/' + applicationId);
        }
        if (responseObject.preApplicationVerificationStatus === 'GenericError') {
          observer.next('application-error/' + personId);
        }
        observer.complete();
      });
    });
    return null;
  }
}

I'm new to rxjs and I think I've made an error with how I am returning observable but I'm struggling a bit. Any help would be appreciated.

1
  • 2
    Both methods say they should return something. One returns null explicitly, the other returns nothing at all. "made an error with how I am returning observable" - not so much an error, as you're not actually doing it.
    – jonrsharpe
    Commented Jul 30, 2018 at 13:50

2 Answers 2

10

This will resolve your issue.

Your issue was that you aren't returning anything, and you are subscribing to your HTTP call. Instead, return the Observable itself, and use pipe(map(...)) to perform actions after your HTTP call without interrupting the chain of actions like subscribe does.

return this.applicationVerificationService.getRouteForFellowshipApplicant(this.personId, this.applicationId)
  .pipe(map(res => {
    console.log(url);

    if (res !== `application-status/${this.personId}/${this.applicationId}`) {
      console.log("failure");
      // this.router.navigateByUrl(url);
      return false;
    } else {
      console.log("success");
      //this.router.navigateByUrl(url);
      return true;
    }
  }));   
}; 
1
  • Thanks your suggestion helped. I didn't realise it was the authguard code that the error message was referring to in the stack. Once I added return call to getRouteForFellowshipApplicant and refactored my code a bit it started working the way I originally wanted it to.
    – nick gowdy
    Commented Jul 30, 2018 at 15:14
0

If you look at the CanActivate method, its return type is boolean, it should be Observable. Also instead of subscribe, you can use .map and return Observable if required.

Hope, this helps. Thanks.

1
  • 1
    This should be a comment. If you can't comment, consider making an actual answer.
    – user4676340
    Commented Jul 30, 2018 at 13:56

Not the answer you're looking for? Browse other questions tagged or ask your own question.