Alos
Alos

Reputation: 11

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

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

Answers (3)

Aairi Rajapaksha
Aairi Rajapaksha

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

Naren Murali
Naren Murali

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

Andres2142
Andres2142

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

Related Questions