Error using HttpClient in canActivate class | [ERROR] NullInjectorError: No provider for _HttpClient

74 Views Asked by At

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

3

There are 3 best solutions below

1
Andres2142 On

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 {}
3
Naren Murali On

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;
    }
}
0
Aairi Rajapaksha On

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.