Əlişiram
Əlişiram

Reputation: 495

How to get result from subsciber as function's return value?

I want to set boolean value of canActivate function based on the result that I get inside subscribeer method. However this gives me an error saying: A function whose declared type is neither 'void' nor 'any' must return a value. I am unable to identify exactly what is wrong with my code and how can I modify it to work?

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

@Injectable({
  providedIn: 'root'
})
export class ProblemAuthGuard implements CanActivate {

  constructor(private apiService: ApiService,
              private router: Router) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    this.apiService.canEdit(route.params['id'])
      .subscribe(obj => {
        if (obj['result'] === 'public') {
          this.router.navigate(['403']);
          return false;
        } else {
          return true;
        }
      });
  }

}

Here is the implementation of canEdit method from apiService:

import { Injectable } from '@angular/core';
import { environment} from '../environments/environment';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs';


const apiUrl = environment.apiURL;

@Injectable({
  providedIn: 'root'
})
export class ApiService {

  constructor(private http: HttpClient) {}

  canEdit(problemId: number): Observable<any> {
    return this.http.get(apiUrl + '/archive/problems/' + problemId + '/visibility');
  }

}

Upvotes: 0

Views: 73

Answers (1)

Roberto Zvjerković
Roberto Zvjerković

Reputation: 10157

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    this.apiService.canEdit(route.params['id'])
      .subscribe(obj => {
        if (obj['result'] === 'public') {
          this.router.navigate(['403']);
          return false;
        } else {
          return true;
        }
      });
  }

Here you're not really returning anything, and you said your method will return boolean.

return false and return true return to your subscribe function, not canActivate function.

But since you're fetching your data asynchronously, you can't return boolean at all, you will have to return Observable still.

Change your code to this:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.apiService.canEdit(route.params['id'])
      .pipe(map(obj => {
        if (obj['result'] === 'public') {
          this.router.navigate(['403']);
          return false;
        } else {
          return true;
        }
      }));
  }

That way you can return Observable of your boolean to your guard (guards can receive boolean, Observable<boolean> and Promise<boolean>).

Upvotes: 2

Related Questions