Mahmoud Niypoo
Mahmoud Niypoo

Reputation: 1710

Angular 4 HTTP request in guard

I'm trying to use an HTTP request inside guard, but always getting errors. when I remove the HTTP request and use an if condition, it's work.

isAdmin.guard.ts

import { Injectable } from '@angular/core';
import { Router ,CanActivate } from '@angular/router';
import { AuthService } from '../services/auth.service';

@injectable()

export class IsAdmin implements CanActivate {
    constructor(
        private auth:AuthService,
        private router:Router
    ){}


    canActivate(){
        //get user data
        this.auth.getUserData().subscribe((data)=>{
            if(data.isAdmin){
                return true;
            }else{
                this.auth.loggedIn();
                this.router.navigate(['/login']);
            }
        })
    }


}

Photo from editor enter image description here

enter image description here

Upvotes: 8

Views: 12644

Answers (2)

Wasit Shafi
Wasit Shafi

Reputation: 1539

The solution is just to return an Observable(from which you can return true or false), as answered by @pedro-arantes but as of now in 2024 with latest Angular/RxJS you have to wrap the map(...) within pipe()

Refer to official docs for pipeable operators

Required Imports:

import { Observable, map } from 'rxjs';

canActivate() handler:

canActivate(): Observable<boolean> {
  return this.auth.getUserData().pipe(
    map((data) => {
      if (data.isAdmin) {
        return true;
      } else {
        this.auth.loggedIn();
        this.router.navigate(["/login"]);
        return false;
      }
    })
  );
}

Hope it helps, Thank you

Upvotes: 0

Pedro Arantes
Pedro Arantes

Reputation: 5379

CanActivate must return a Observable<boolean> | Promise<boolean> | boolean as you can see in this link.

interface CanActivate { 
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean
}

In your case, you should only return this.auth.getUserData(). But such function doesn't return an Observable<boolean>, instead, it returns Observable<data>. So you should map it to return a Observable<boolean>:

canActivate(): Observable<boolean> {
    //get user data
    return this.auth.getUserData().map((data)=>{
        if(data.isAdmin){
            return true;
        }else{
            this.auth.loggedIn();
            this.router.navigate(['/login']
            return false;
        }
    })
}

Upvotes: 11

Related Questions