The issue of Undefined TypeError arises when using Angular HttpInterceptor and injecting any service

Issue:

I'm facing a problem where I am unable to inject any service into the constructor of my HttpInterceptors. Every service I try to inject results in the error:

TypeError: Cannot set property 'authenticationService' of undefined

Even a simple dummy service like foo with a single function bar without any additional dependencies results in the same error.

CODE SNIPPET

interceptor.ts

import { Injectable, Injector } from '@angular/core';
import {
    HttpRequest,
    HttpHandler,
    HttpEvent,
    HttpInterceptor
} from '@angular/common/http';
import { AuthenticationService } from '../authentication/authentication.service';
import { Observable } from 'rxjs';

@Injectable({
    providedIn: 'root'
})
export class Interceptor implements HttpInterceptor {

    constructor(private authenticationService: AuthenticationService) { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        if (request.url.includes(location.hostname) && this.authenticationService.getToken()) {
            console.log('Headers added to the HTTP Request');
            request = request.clone({
                setHeaders: {
                    Authorization: `Bearer ${this.authenticationService.getToken()}`
                }
            });
        }
        return next.handle(request);
    }
}

authentication.service.ts

import { OnInit, Injectable } from '@angular/core';
import { AuthServiceConfig, AuthService as SocialAuthService, FacebookLoginProvider, GoogleLoginProvider, SocialUser} from 'angularx-social-login';
import { HttpClient, HttpRequest } from  '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { environment } from '../../../environments/environment';
import { JwtHelperService } from '@auth0/angular-jwt';

@Injectable( { providedIn: "root" } )

export class AuthenticationService implements OnInit{

  jwtHelper: JwtHelperService = new JwtHelperService();
  socialLoginConfig: AuthServiceConfig;
  loggedIn: BehaviorSubject<Boolean> = new BehaviorSubject<Boolean>(false);
  loggedIn$: Observable<Boolean> = this.loggedIn.asObservable();
  user: BehaviorSubject<SocialUser> = new BehaviorSubject(null);
  user$: Observable<SocialUser> = this.user.asObservable();

  cachedRequests: Array<HttpRequest<any>> = [];

  constructor(private socialAuthService: SocialAuthService, private http: HttpClient) { }

  // Rest of the methods in the AuthenticationService class...

app.module.ts

import { environment } from '../environments/environment';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { LoginComponent } from './modules/public/pages/login/login.component';
import { SocialLoginModule, AuthServiceConfig } from "angularx-social-login";
import { GoogleLoginProvider, FacebookLoginProvider } from "angularx-social-login";

import { NavbarComponent } from './shared/components/navbar/navbar.component';
import { FooterComponent } from './shared/components/footer/footer.component';
import { HomeComponent } from './modules/public/pages/home/home.component';
import { UserComponent } from './modules/secure/pages/user/user.component';

import { HttpClientModule, HTTP_INTERCEPTORS} from '@angular/common/http';
import { Interceptor } from './core/interceptors/interceptor';
import { DashboardComponent } from './modules/secure/pages/dashboard/dashboard.component';

// Rest of the app.module.ts file...

Investigation/Problem-solving Attempted:

I have researched various posts and forums that suggest issues when injecting a service containing an HTTPClient reference, leading to a cyclic dependency error resulting in 'undefined'. Although this issue was reportedly fixed in an Angular 5 patch, I am currently using Angular 7 for this project.

I tried injecting an Injector instead of directly injecting the authenticationService into the constructor and then setting

this.authenticationService = this.injector.get(AuthenticationService);
, which resulted in the error:

TypeError: Cannot set property 'injector' of undefined

Additionally, I attempted to modify the provider for the HttpInterceptor in app.module.ts to:

{ provide: HTTP_INTERCEPTORS, useFactory: Interceptor, multi: true, deps: [AuthenticationService] }

However, this also led to the same undefined error.

Conclusion:

Apologies for the lengthy details, but I wanted to provide all the relevant information in hopes of resolving this issue that has caused me significant frustration. Thank you in advance for any assistance!

Answer №1

Encountering a similar issue led me to switch from using useFactory to useClass within the module declaration:

This code snippet originally functioned in Angular 7.1

{
    provide: HTTP_INTERCEPTORS,
    useFactory(router: Router, authenticationStorageService: AuthenticationStorageService) {
        // all the necessary operations here

        return new AuthInterceptor(router, authenticationStorageService);
    },
    multi: true,
    deps: [Router, AuthenticationStorageService]
},

However, this approach failed in Angular 8. Removing the factory resolved the issue:

{
    provide: HTTP_INTERCEPTORS,
    useClass: AuthInterceptor,
    multi: true,
    deps: [Router, AuthenticationStorageService]
},

Adjusting the logic to the constructor of the class was the workaround. While the factory method allowed for more flexibility in switching instances, it may have been excessive for the standard use case.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The server's file URLs are modified within the page source of a WordPress site

I've been attempting to integrate Adsense code into a WordPress blog at demonuts.com. I placed the Google code in the TEXT WIDGET provided by WordPress. However, upon running the website, I noticed that the URLs for .js, .css, or .png files are being ...

The Angular directive is failing to refresh the data on the Google Map

I created a directive called "myMap" to incorporate a Google map into my application. However, I am facing an issue when attempting to update the longitude and latitude values for a different location using a controller function. The directive does not ref ...

Tips for implementing an autoscroll feature in the comments section when there is an abundance of comments

Having a large number of comments on a single post can make my page heavy and long sometimes. This is the current layout of my post comment system: Post 1 Comment for post 1 //if comments are more than 3 <button class="view_comments" data-id="1">Vi ...

Filter information by the K column within Google Script Editor on Google Sheets

For this particular case, I have data coming from a Google Sheet (4Cat) that is being transferred to another sheet (ImportFeeder) where my Google Script is executed. After executing the script provided below, I am looking to implement a filter script at t ...

Retrieving JSON data in Angular 5 returns a 400 bad request error

Having trouble calling the REST API of Amazon S3 from Angular 5. Keep getting a 400 bad request error. This problem has been persisting for a while now and I really need to find a solution or at least get some suggestions on where the issue might be. Her ...

Obtaining JSON information with Svelte

I'm currently facing a mental block. My goal is to fetch JSON data using the Youtube API. The error message I am encountering is "Cannot read property 'getJSON' of undefined". Here's the code snippet I have provided: <script> ...

What is the best way to retrieve the updated value following a mutation in Vuex?

In my Vuex module, I have a simple setup for managing a global date object: import moment from 'moment'; const state = { date: moment() } // getters const getters = { date: state => state.date, daysInMonth: state => state.dat ...

Is Nextjs the best choice for developing the frontend code exclusively?

When deciding whether to use Next.js or plain React for my front-end development, should I consider that a back-end already exists? If I am not planning to write a new back-end, which option would be better suited for the project? ...

All browsers experiencing issues with autoplay audio function

While creating an HTML page, I decided to include an audio element in the header using the code below: <audio id="audio_play"> <source src="voice/Story 2_A.m4a" type="audio/ogg" /> </audio> <img class= ...

Possible Inconsistencies with the LookAt Feature in Three.js

Attempting to use the lookAt function to make zombies move towards the character has been a challenge. The problem lies in the fact that they are not turning correctly but at odd angles. Here is the code snippet I tried: var pos = new THREE.Vector3(self ...

Path to local image in JavaScript

Apologies for the newbie question, but I'm trying to display a gif on a webpage using an HTTP link and it works perfectly. However, when I try to replace it with a file path, it doesn't work. The gif is located in the same folder as the webpage. ...

Is it possible to conduct an auction in JavaScript without using the settimeout or setinterval functions?

I'm currently working on creating an auction site and I need help improving its speed and performance. I've been using setInterval and setTimeout functions for the countdown, but it's quite slow as a request is sent to the server every secon ...

Utilize multiple activated modules in Angular 2

Recently, I've been exploring the new features of Angular 2 final release, particularly the updated router functionality. An interesting example showcasing the router in action can be found at this link: http://plnkr.co/edit/mXSjnUtN7CM6ZqtOicE2?p=pr ...

Is it possible to upgrade just the rxjs version while keeping all other components at their current versions?

While working on my Angular 4 project, I encountered a problem when trying to use a WebSocket package from GitHub. After running npm install to upgrade the rxjs version, I faced errors. Even after attempting to upgrade just the rxjs version and running ng- ...

Using Jquery to access the grandparent element

When I have code similar to what is shown below, an element contains within 3 layers: <span class="dropdown test1"> <span class="test2" type="button" data-toggle="dropdown">hello</span> <ul class="dropdown-menu test3" style="m ...

Issue with Bootsrap 4 Dropdown Menu Displaying Incomplete Links

There seems to be an issue with the Bootstrap 4 dropdown menu not displaying all the links. Please refer to the image below: https://i.sstatic.net/ZS2t2.png The dropdown menu is not showing beyond the red band. I can't seem to figure out what I&apos ...

Include a hash in the URL when the current location is entered into the view by scrolling

In my current situation, I am required to implement a @HostListener in order to navigate to an element within my web page: @HostListener('click', ['$event']) onClick(e: any) { e.preventDefault(); const href = e.target.getAttri ...

Customizing the MUI X Sparkline: Incorporating the percentage symbol at the end of the tooltip data within the MUI Sparklinechart

Presented below is a SparklineChart component imported from MUI X: import * as React from 'react'; import Stack from '@mui/material/Stack'; import Box from '@mui/material/Box'; import { SparkLineChart } from '@mui/x-chart ...

Is there a Page Views tracker in sinatra?

Help needed with implementing a page views counter using Sinatra and Ruby. I attempted using the @@ variables, but they keep resetting to zero every time the page is reloaded... Here's an example: Appreciate any advice! ...

I'm having trouble with my Selenium as it doesn't seem to be able to open

Hey there, I've been working on a script to login to Gmail, but I'm having trouble with entering the password after entering the email. public static void main(String[] args) throws Exception { System.setProperty("webdriver.chrome.driver", "E:&b ...