Reputation: 11
I've some troubles when I want to use HttpClient in a CanActivate class. I want to do some POST request in order to find my token in a Django API. Examples are better than words :
auth.guard.ts :
import { Injectable, NgModule } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { HttpClient, HttpClientModule } from "@angular/common/http";
@Injectable({
providedIn: 'root'
})
export class AuthGuardService implements CanActivate {
constructor(private router: Router,
private http: HttpClient,
) { }
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
const expectedRole: string[] = route.data['expectedRole'];
if (localStorage.getItem('token') == null) {
this.router.navigate(['http://localhost:3000']);
return false;
}
this.http.post<any>('api/verify-token/', {
token: localStorage.getItem('jwt')
}).subscribe((data) => {
if (!expectedRole.includes(data.role)) {
this.router.navigate(['http://localhost:3000']);
}
return true;
}, err => {
this.router.navigate(['http://localhost:3000']);
return false;
}
)
return false;
}
}
app.route.ts :
import { Routes, RouterModule } from '@angular/router';
import { AddUserComponent } from './add-user/add-user.component';
import { NgModule } from '@angular/core';
import { AuthGuardService } from './auth.guard';
export const routes: Routes = [
// routes...
{ path: 'add-user', component: AddUserComponent, canActivate: [AuthGuardService], data: { expectedRole: ['Administrateur'] } },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: []
})
export class AppRouteModule { }
also, this is my app.module.ts
:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [],
imports: [
BrowserModule,
HttpClientModule, // Import the HttpClientModule here
],
providers: [],
bootstrap: []
})
export class AppModule {}
and when I try to access to my route, I have this error :
ERROR Error [NullInjectorError]: R3InjectorError(Environment Injector)[_AuthGuardService -> _HttpClient -> _HttpClient]:
NullInjectorError: No provider for _HttpClient!
at NullInjector.get
at R3Injector.get
at R3Injector.get
at injectInjectorOnly
at Module.ɵɵinject
at Object.AuthGuardService_Factory
at eval
at runInInjectorProfilerContext
at R3Injector.hydrate
at R3Injector.get {
ngTempTokenPath: null,
ngTokenPath: [ '_AuthGuardService', '_HttpClient', '_HttpClient' ]
Can you explain me where I'm wrong please
Upvotes: 1
Views: 136
Reputation: 56
Ensure that you have imported HttpClientModule in the module where your AuthGuardService is declared.
If the issue persists, try restarting the development server. Sometimes, the Angular development server may not pick up changes correctly. Stop the server (Ctrl + C in the terminal) and restart it using the command: ng serve
.
Upvotes: 0
Reputation: 58612
When using services provided in root
then you can use inject()
to add the dependencies like shown below!
import { Injectable, NgModule, inject } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { HttpClient, HttpClientModule } from "@angular/common/http";
@Injectable({
providedIn: 'root'
})
export class AuthGuardService implements CanActivate {
private router = inject(Router));
private http= inject(HttpClient));
constructor() { }
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
const expectedRole: string[] = route.data['expectedRole'];
if (localStorage.getItem('token') == null) {
this.router.navigate(['http://localhost:3000']);
return false;
}
this.http.post<any>('api/verify-token/', {
token: localStorage.getItem('jwt')
}).subscribe((data) => {
if (!expectedRole.includes(data.role)) {
this.router.navigate(['http://localhost:3000']);
}
return true;
}, err => {
this.router.navigate(['http://localhost:3000']);
return false;
}
)
return false;
}
}
Upvotes: 0
Reputation: 2917
You need to import HttpClientModule
into the app.module.ts
or the root module you are using
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [...],
imports: [HttpClientModule],
providers: [...]
})
export class AppModule {}
Upvotes: 2