Reputation: 1710
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']);
}
})
}
}
Upvotes: 8
Views: 12644
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
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