Angular 8: Cannot instantiate cyclic dependency - ActivatedRoute
Asked Answered
U

5

8

I am trying to integrate the APP_INITIALIZER from Angular in my project in order to do some functionalities before start the application. The problem comes when I use the ActivatedRoute from Angular in my service.

The error is:

Error: Provider parse errors:
Cannot instantiate cyclic dependency! ApplicationRef ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1

I suppose that I am using some import twice internally or something like this. Basically i tried with some other configurations but at the end always is throwing me the same error.

STACKBLITZ EXAMPLE: https://stackblitz.com/edit/angular-bhpe7m

Expected behavior: Just to be able to retrieve some QueryParams by the ActivatedRoute service and do some functionality with them before run the Angular app

Untouched answered 25/7, 2019 at 15:56 Comment(7)
Thanks for the formating @nircraft :)Untouched
In shared stackblitz : the AppLoadModule works as another feature module, Your APP_INITIALIZER should be in the AppModule which is referenced and bootstrapped in main.tsDonovan
Possible duplicate of APP_INITIALIZER raises "Cannot instantiate cyclic dependency! ApplicationRef_" when used with a custom Http provider that is redirectingDonovan
I know, but I was trying to do it separately, like this example: intertech.com/Blog/…Untouched
you can also check this: #46441639Donovan
you are not having any routesColza
Yes, because for now I don't need any other page on my applicationUntouched
C
7

Got your problem just remove router from your 'appLoaderService'

  constructor(private route: ActivatedRoute) {} // remove this dependency

You are getting cyclic dependency since you are injecting route in the config which initializes your app.

Refer this

Simply, remove this since you are not using it anyways.

However if you indent to use route before your bootstrapping component loads, you can go for resolver or guards.

As mentioned, it is not possible to use routes inside APP_INITIALIZER, *though there is a way**, but i would better suggest to use Resolver as following:

resolve(route: ActivatedRouteSnapshot): Promise<any> {
    const promise = new Promise((resolve, reject) => {
      if (route) {
        console.log(route.params);
        console.log(route.queryParams);
      }
 }
return promise;
}

Resolver for reference

EDIT Here is what you will have after placing code in resolver :

enter image description here

Cheddite answered 25/7, 2019 at 16:15 Comment(8)
I know that, but in fact i need to use it, i was not showing it before in the stackblitx example but now it is updated. Because I need to store the query params retrieved at the start of the application in some variables.Untouched
i had faced the similar issue, if you put route inside your config, even then your component will not be loaded, now suppose you initializes couple of things in your app, you cannot show spinner component since "config" is the first thing which is loaded, moreover it is absurd to show your client blank screen unless you are done with all dependencies inside app.config. Let, me edit my answer, how can you read your query params via ResolverCheddite
It make sense, but how can i call the resolve method passing to it the route object? Example: stackblitz.com/edit/angular-bhpe7mUntouched
here check this example for you, please note as best practices you have to keep separate file for Resolver, and believe me this will help you resolving so many concerns in near future, which i had faced.Cheddite
wow it seems like it is working for yoy, can you share this code in a stackblitz? the current one seems like its not updated.Thanks a lot for your helping @ChedditeUntouched
I don't really get the solution, and the stackblitz example it's not working as the image in your comment on top. What is exactly doing the appload service now? Thanks a lotUntouched
My bad, shared you the wrong url, here you goCheddite
Let us continue this discussion in chat.Untouched
T
14

Make sure to include HttpClientModule in your app.module.ts

import { HttpClientModule } from '@angular/common/http';

@NgModule({
   declarations: [
      AppComponent
   ],
   imports: [
      BrowserModule,
      AppRoutingModule,
      HttpClientModule
   ],
})
export class AppModule { }
Townley answered 14/5, 2020 at 12:10 Comment(0)
C
7

Got your problem just remove router from your 'appLoaderService'

  constructor(private route: ActivatedRoute) {} // remove this dependency

You are getting cyclic dependency since you are injecting route in the config which initializes your app.

Refer this

Simply, remove this since you are not using it anyways.

However if you indent to use route before your bootstrapping component loads, you can go for resolver or guards.

As mentioned, it is not possible to use routes inside APP_INITIALIZER, *though there is a way**, but i would better suggest to use Resolver as following:

resolve(route: ActivatedRouteSnapshot): Promise<any> {
    const promise = new Promise((resolve, reject) => {
      if (route) {
        console.log(route.params);
        console.log(route.queryParams);
      }
 }
return promise;
}

Resolver for reference

EDIT Here is what you will have after placing code in resolver :

enter image description here

Cheddite answered 25/7, 2019 at 16:15 Comment(8)
I know that, but in fact i need to use it, i was not showing it before in the stackblitx example but now it is updated. Because I need to store the query params retrieved at the start of the application in some variables.Untouched
i had faced the similar issue, if you put route inside your config, even then your component will not be loaded, now suppose you initializes couple of things in your app, you cannot show spinner component since "config" is the first thing which is loaded, moreover it is absurd to show your client blank screen unless you are done with all dependencies inside app.config. Let, me edit my answer, how can you read your query params via ResolverCheddite
It make sense, but how can i call the resolve method passing to it the route object? Example: stackblitz.com/edit/angular-bhpe7mUntouched
here check this example for you, please note as best practices you have to keep separate file for Resolver, and believe me this will help you resolving so many concerns in near future, which i had faced.Cheddite
wow it seems like it is working for yoy, can you share this code in a stackblitz? the current one seems like its not updated.Thanks a lot for your helping @ChedditeUntouched
I don't really get the solution, and the stackblitz example it's not working as the image in your comment on top. What is exactly doing the appload service now? Thanks a lotUntouched
My bad, shared you the wrong url, here you goCheddite
Let us continue this discussion in chat.Untouched
L
1

This is happening due to a loop in dependency injection, for example you have injected a service into itself in its constructor!

Loch answered 30/11, 2021 at 7:22 Comment(1)
This was my answer! I had code that was Injecting itself instead of the MatDialogRef @Inject(ThresholdRequirementEditComponent) public thisDialogRef: MatDialogRef<ThresholdRequirementEditComponent>Kagera
H
0

In my case I had a ConfigService loading its configuration using http service.

This ConfigService was injected inside an HttpInterceptor.

But http service needs HttpInterceptor and HttpInterceptor needs ConfigService that needs http.

A simple workaround solution was to use from(fetch('/config').then(resp=>resp.json())) instead of http.get('/config') inside the HttpInterceptor to avoid the cyclic dependency.

In any case there is no need to have an HttpInterceptor running for loading HttpInterceptor's configuration.

Hon answered 7/12, 2022 at 20:9 Comment(0)
P
-5

I solved it by updating the package using the following code.

ng add @angular/localize
Proportionate answered 10/8, 2020 at 17:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.