gilsdav / ngx-translate-router

Translate routes using ngx-translate
130 stars 43 forks source link

Circular dependency in DI detected for Router #94

Open ghost opened 3 years ago

ghost commented 3 years ago

When trying to use latest library version with Angular v10 I'm receiving errors connected with library.

zone-evergreen.js:659 Unhandled Promise rejection: NG0200: Circular dependency in DI detected for Router ; Zone: ; Task: Promise.then ; Value: Error: NG0200: Circular dependency in DI detected for Router at throwCyclicDependencyError (core.js:2204) at R3Injector.hydrate (core.js:11676) at R3Injector.get (core.js:11501) at injectInjectorOnly (core.js:891) at Module.ɵɵinject (core.js:895) at Object.LocalizeRouterService_Factory [as factory] (gilsdav-ngx-translate-router.js:808) at R3Injector.hydrate (core.js:11680) at R3Injector.get (core.js:11501) at injectInjectorOnly (core.js:891) at ɵɵinject (core.js:895) Error: NG0200: Circular dependency in DI detected for Router at throwCyclicDependencyError (http://localhost:4200/vendor.js:51865:11) at R3Injector.hydrate (http://localhost:4200/vendor.js:61337:13) at R3Injector.get (http://localhost:4200/vendor.js:61162:33) at injectInjectorOnly (http://localhost:4200/vendor.js:50552:33) at Module.ɵɵinject (http://localhost:4200/vendor.js:50556:57) at Object.LocalizeRouterService_Factory [as factory] (http://localhostl:4200/vendor.js:37553:320) at R3Injector.hydrate (http://localhost:4200/vendor.js:61341:35) at R3Injector.get (http://localhost:4200/vendor.js:61162:33) at injectInjectorOnly (http://localhost:4200/vendor.js:50552:33) at ɵɵinject (http://localhost:4200/vendor.js:50556:57) <

My implementation looks like below:

export function ManualLoaderFactory(translate: TranslateService, location: Location, settings: LocalizeRouterSettings) {
  return new ManualParserLoader(translate, location, settings, ['pl', 'int', 'pl_en'], 'route.');
}

export const routingConfiguration: ExtraOptions = {
  paramsInheritanceStrategy: 'always',
  relativeLinkResolution: 'legacy'
};

@NgModule({
  imports: [
    RouterModule.forRoot(MODULES_ROUTES, routingConfiguration),
    LocalizeRouterModule.forRoot(MODULES_ROUTES, {
      parser: {
        provide: LocalizeParser,
        useFactory: ManualLoaderFactory,
        deps: [TranslateService, Location, LocalizeRouterSettings]
      }
    })
  ],
  exports: [LocalizeRouterModule, RouterModule]
})
gilsdav commented 3 years ago

@tmkd92 Do you still have the issue ?

ghost commented 3 years ago

Hello @gilsdav, yes I am. Apart from above I found that on Angular v9 there is no issue with Router dependency. It looks like some changes has been applied to ngcc towards angular router..

gilsdav commented 3 years ago

That's quite strange because you can see in this project, it works as expected in ng 10 and 11: https://github.com/gilsdav/angular-universal-localize-router

Do you have something like an Injector that uses the Router ?

ghost commented 3 years ago

My AppComponent is using Router as DI, could that cause the problem here?

gilsdav commented 3 years ago

Definitly not. Is it possible for you to share de reproduction project ?

timrasche commented 3 years ago

Same here. Use APP_INITIALIZER in providers section. APP_INITIALIZER use a service as dependency that is provided in root. Secondary i use a http interceptor... if remove both, no error shown. Cant figure it out.

WheelyWonka commented 3 years ago

Hi @gilsdav, thank you for your work. I'm building a custom boilerplate that must be able to work with and without SSR. Everything works great in SSR mode (at least with npm run dev:ssr) but when i try to start the project with npm start i get the same error as @tmkd92.

// app.module

@NgModule({
  declarations: [AppComponent, AtomLangSelectComponent],
  imports: [
    BrowserModule,
    BrowserModule.withServerTransition({ appId: 'app-name' }),
    TransferHttpCacheModule,
    AppRoutingModule,
    ServiceWorkerModule.register('ngsw-worker.js', {
      enabled: environment.production,
    }),
    SharedModule,
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}
// app.server.module

@NgModule({
  imports: [
    AppModule,
    ServerModule,
    ServerTransferStateModule,
    TranslateModule.forRoot({
      defaultLanguage: Object.keys(environment.i18n.availableLanguages)[0],
      loader: {
        provide: TranslateLoader,
        useFactory: translateServerLoaderFactory,
        deps: [TransferState],
      },
    }),
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppServerModule {}
// shared.module

@NgModule({
  declarations: [],
  imports: [
    FormsModule,
    HttpClientModule,
    BrowserAnimationsModule,
    CommonModule,
    TranslateModule.forRoot({
      defaultLanguage: Object.keys(environment.i18n.availableLanguages)[0],
      loader: {
        provide: TranslateLoader,
        useFactory: translateBrowserLoaderFactory,
        deps: [HttpClient, TransferState],
      },
    }),
    NzSelectModule
  ],
  exports: [
    FormsModule,
    HttpClientModule,
    BrowserAnimationsModule,
    CommonModule,
    TranslateModule,
    NzSelectModule
  ],
  providers: [],
})
export class SharedModule {}
// app-routing.module

export function LocalizeRouterTranslateLoader(
  translate: TranslateService,
  location: Location,
  settings: LocalizeRouterSettings
): ManualParserLoader {
  return new ManualParserLoader(
    translate,
    location,
    settings,
    Object.keys(environment.i18n.availableLanguages),
    'ROUTES.'
  );
}

const routes: Routes = [];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      initialNavigation: 'disabled',
    }),
    LocalizeRouterModule.forRoot(routes, {
      parser: {
        provide: LocalizeParser,
        useFactory: LocalizeRouterTranslateLoader,
        deps: [TranslateService, Location, LocalizeRouterSettings],
      },
      initialNavigation: true,
    }),
  ],
  exports: [RouterModule, LocalizeRouterModule],
})
export class AppRoutingModule {}

Something i'm missing ? Thank you for your help !

WheelyWonka commented 3 years ago

I fixed my case by removing the parameter defaultLanguage in TranslateModule.forRoot() declared in shared.module and app.server.module. I supposed that since LocalizerRouter has its own logic to find the default language to set, it was creating a conflict or something ? Would be curious to understand the exact issue if you find it.

Now everything works in SSR and in SLA modes !

richie50 commented 3 years ago

image

I'm experiencing the same issue. I have followed the import guide. I'm on angular 11

Followed @WheelyWonka fixed and it resolved it for me. The documentation is really hard to follow. Can the owners to include more examples and a clearer setup. Thanks

AndriyKagui commented 3 years ago

@WheelyWonka, thanks, helped in my case

pr-nextre commented 3 years ago

@WheelyWonka You goddamnit hero! I've been losing my mind on this one

ullalaaron commented 3 years ago

@WheelyWonka you're the man!

cabaji9 commented 1 year ago

On my case the error was -->

 const browserLang = translate.getBrowserLang();
 translate.use(browserLang.match(/en|es/) ? browserLang : 'es');

This getBrowserLang caused the router error fixed with:

const language = translate.getDefaultLang();

gvestit commented 8 months ago

Hi,

If I don't put it on TranslateModule.forRoot I get a blank page with unknown error. What it can be causing it?

If i manually put in localstorage key lang with value en or es . It works

abhijit-chikane commented 6 months ago

I fixed my case by removing the parameter defaultLanguage in TranslateModule.forRoot() declared in shared.module and app.server.module. I supposed that since LocalizerRouter has its own logic to find the default language to set, it was creating a conflict or something ? Would be curious to understand the exact issue if you find it.

Now everything works in SSR and in SLA modes !

@WheelyWonka Thanks you saved my day!!