Angular 5 APP_INITIALIZER: Provider parse error - Cyclic dependency instantiation not possible

I am utilizing the APP_INITIALIZER token to execute a task upon page load before my Angular application is initialized. The service responsible for this functionality relies on another service located within my CoreModule.

The issue at hand seems to be about injecting the AuthService into my AppService. Although I cannot pinpoint why it's causing a problem. After all, AuthService does not inject AppService, so where does the circular dependency come from?

This is the error message I'm encountering:

> Uncaught Error: Provider parse errors: Cannot instantiate cyclic
> dependency! ApplicationRef ("[ERROR ->]"): in NgModule AppModule in
> ./AppModule@-1:-1 Cannot instantiate cyclic dependency! ApplicationRef
> ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1
>     at NgModuleProviderAnalyzer.parse (compiler.js:19550)
>     at NgModuleCompiler.compile (compiler.js:20139)
>     at JitCompiler._compileModule (compiler.js:34437)
>     at eval (compiler.js:34368)
>     at Object.then (compiler.js:474)
>     at JitCompiler._compileModuleAndComponents (compiler.js:34366)
>     at JitCompiler.compileModuleAsync (compiler.js:34260)
>     at CompilerImpl.compileModuleAsync (platform-browser-dynamic.js:239)
>     at PlatformRef.bootstrapModule (core.js:5567)
>     at bootstrap (main.ts:13)

Below is my AppModule:

import { NgModule, APP_INITIALIZER } from '@angular/core';

import { AppService, AppServiceFactory } from './app.service';
import { CoreModule } from 'core';

@NgModule({
    imports: [
        // ...
        CoreModule,
        // ...
    ],
    providers: [
        AppService,
        {
            provide: APP_INITIALIZER,
            useFactory: AppServiceFactory,
            deps: [AppService],
            multi: true
        }
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent]
})
export class AppModule {}

Here is the implementation of AppService:

import { Injectable } from '@angular/core';

import { finalize } from 'rxjs/operators';

import { AuthService } from 'core/services/auth/auth.service';

export function AppServiceFactory(appService: AppService): () => Promise<any> {
    return () => appService.doBeforeBootstrap();
}

@Injectable()
export class AppService {
    constructor(private authService: AuthService) {}

    doBeforeBootstrap(): Promise<any> {
        return new Promise(resolve => {
            this.authService.isLoggedIn().then((loggedIn: boolean) => {
                if (loggedIn) {
                    return resolve();
                }

                this.authService.refreshToken().pipe(
                    finalize(() => resolve())
                ).subscribe();
            });
        });
    }
}

Does anyone understand why such an error is being triggered?

Edit (dependencies of AuthService):

constructor(
    private ref: ApplicationRef,
    private router: Router,
    private http: HttpClient,
    // Other custom services that are NOT imported into AppService...
) {}

Answer №1

When utilizing APP_INITIALIZER, make sure to provide a factory that relies on AppService, which in turn depends on AuthService, ultimately depending on ApplicationRef. This dependency chain leads back to ApplicationInitStatus and eventually loops back to APP_INITIALIZER... what a setup!

To delve deeper into this topic, check out the following links: https://github.com/angular/angular/blob/5.2.9/packages/core/src/application_init.ts and https://github.com/angular/angular/blob/5.2.9/packages/core/src/application_ref.ts specifically at line 398.

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

ReactJs Error: Unable to access property value because it is undefined (trying to read '0')

I am currently attempting to retrieve and display the key-value pairs in payload from my JSON data. If the key exists in the array countTargetOptions, I want to show it in a component. However, I am encountering an error message stating Uncaught TypeError ...

Trouble encountered with uploading files using Multer

I am facing an issue with uploading images on a website that is built using React. The problem seems to be related to the backend Node.js code. Code: const multer = require("multer"); // Check if the directory exists, if not, create it const di ...

A Vue component library devoid of bundled dependencies or the need for compiling SCSS files

My current challenge involves the task of finding a way to publish our team's component library. These components are intended to be used by various internal applications within our organization. I have specific requirements: The library must be acc ...

Typescript UniqueForProp tool not working as expected

I've created a utility function called UniqueForProp that takes an array of objects and a specified property within the object. It then generates a union type containing all possible values for that property across the array: type Get<T, K> = K ...

Angular throws a NullInjectorError when a unit test fails due to issues with dependency

As a newcomer to Angular, I am struggling to grasp the concept of Dependency Injection (DI) and how it functions. My current challenge involves trying to pass a unit test successfully. Below is the code for the test; import { TestBed } from '@angula ...

Navigating the complexities of Angular 2+ modules, exports, and services: preventing duplication of shared/reusable services

Imagine if I have the following scenario: I have imported import { HttpModule } from '@angular/http'; into my main application module (BrowserModule). In my application, I am using the Http service through dependency injection in various parts of ...

Can you explain the distinction between the fontawesome angular package, the standard npm package, and simple sass?

In my new Angular CLI project (version 8+) that is using Sass (SCSS), I have been exploring the Fontawesome documentation and discovered there are several methods for hosting Fontawesome icons. These include installing the npm package, integrating the angu ...

Tips for effectively simulating the formik useFormikContext function while writing unit tests using jest

I've created a simple component (shown below) that aims to fetch data from the Formik FormContext using the useFormikContext hook. However, I'm facing some challenges when writing unit tests for this component. It requires me to mock the hook, w ...

Accessing properties for objects with map-like characteristics

Many interfaces allow for arbitrary data, as shown below: interface Something { name: string; data: { [key: string]: any }; } The problem arises when trying to access or set values on objects with arbitrary keys in Typescript. let a: Something = { ...

The dependencies of Nest are unable to be resolved by the system

Attempting to implement AuthService within UsersService and UsersService within AuthService results in a "circular dependency" issue. The error message states that "Nest can't resolve dependencies of the AuthService (UserModel, JwtService, ?). Please ...

In TypeScript, the 'as const' syntax results in a syntax error due to the missing semicolon

I incorporated the following code into my react project: export const animation = { WAVES: "waves", PULSE: "pulse", } as const; export type Animation = typeof animation[keyof typeof animation]; Upon running the project, I encounte ...

Issues with exporting function and interface have been identified

When exporting a function and type from the library in the convertToUpper.ts file, I have the following code: export function Sample() { console.log('sample') } export type IProp = { name: string age: number } The index.ts file in my lib ...

Exploring Mikro-ORM with Ben Awad's Lireddit: Navigating the Process of Running Initial Migrations

Having some trouble following the lireddit tutorial, particularly with the initial mikro-orm migration step. Encountering a similar issue as mentioned in this post. Tried modifying the constructor of the example entity (tried both provided format and the ...

Breaking down the steps to flip between two images when clicked in Vue.js

I'm currently trying to implement a feature in Vue.js where images switch on click. The functionality I'm aiming for is as follows: Upon initial load, the image displays in black, then upon clicking/selecting it, the image transitions into a blu ...

Strategies for increasing the number of images in Angular

At the start, 15 images are displayed from the API. However, the "Get dogs" button should load an additional 15 images each time it's clicked, but currently, it doesn't work. How can we fix this issue? http.service.ts - a service that interacts ...

Angular HttpInterceptor Unit Test: toHaveBeenCalledWith method shows no sign of being called

I have been working on unit testing an error-handling interceptor and encountered an issue with the toHaveBeenCalledWith function. It keeps giving a "but it was never called" message in the console. Can anyone shed some light on why this might be happening ...

Developing a custom package containing personally crafted type definitions and importing them into the project

I'm in need of creating a private npm package specifically for custom type definitions (typedefs) that are hand-written d.ts files not generated by TypeScript. Since these are proprietary, they cannot be added to DefinitelyTyped. The folder structure ...

Adding a new key to a specific position in an array using Angular

After organizing my array, here is what it currently looks like: 0: Object { row: 0 } 1: Object { row: 1 } 2: Object { row: 2 } 3: Object { row: 3 } Now, I need to add a new key to position 2. The updated structure should resemble this: 0: Object { row: 0 ...

Angular IIFE functions being executed prior to the DOM being fully loaded

Currently, I am working on building an application with angular 6. In my project, there is a JavaScript framework file that includes some common event binding logic implemented as Immediately Invoked Function Expressions (IIFE). The issue I am facing is t ...

The ngAfterViewInit lifecycle hook does not get triggered when placed within ng-content

The ngAfterViewInit lifecycle hook isn't triggered for a Component that is transcluded into another component using <ng-content>, as shown below: <app-container [showContent]="showContentContainer"> <app-input></app-input> ...