title: ERROR NullInjectorError: R3InjectorError(AppModule) - Using DI for angular content translation
body: <p>I have an angular project which has the following architecture (i removed hml &amp; css) :</p>
  <pre><code>|_ app.component.ts
  |_ app.module.ts
  |_ app-routing-module.ts
  |_ components
     |_ site
          |_ site.component.ts
          |_ site.module.ts
          |_ site.en.module.ts
          |_ site.fr.module.ts
          |_ site-routing-module.ts
             |_ home
                 |_ home.component.ts
                 |_ home.module.ts
                 |_ home.en.module.ts
                 |_ home.fr.module.ts
                 |_ home-routing-module.ts
                     |_ pdf-viewer-form
                         |_ pdf-viewer-form.component.ts
                     |_ pdf-viewer-from-server
                         |_ pdf-viewer-from-server.component.ts
             |_ info
                 |_ info.component.ts
                 |_ info.module.ts
                 |_ info.en.module.ts
                 |_ info.fr.module.ts
                 |_ info-routing-module.ts
     |_ theme
             |_ header
                 |_ header.component.ts
                 |_ header.module.ts
                 |_ header.en.module.ts
                 |_ header.fr.module.ts
                 |_ header-routing-module.ts
  </code></pre>
  <p>For this project I tried to implement i18n using dependency injection and lazy-loading.
  For this I implemented a typescript file with this content :</p>
  <pre><code>import { InjectionToken } from '@angular/core';
  import { en } from './en.translation';
  
  export enum WebsiteLanguage {
    English = 'en',
    French = 'fr',
  }
  export type Translation = typeof en;
  export const TRANSLATION = new InjectionToken&lt;Translation&gt;('TRANSLATION');
  </code></pre>
  <p>And a translation file :</p>
  <pre><code>export const fr = {
    language: 'Français',
    home: {
      title: 'La page d\'accueil marche',
    },
    upload: {
      title: 'La page Upload marche!',
    },
  
    langsSupported: (n: number) =&gt; `Cette démon inclut ${n} langues ${n === 1 ? '' : 's'}.`,
  };
  </code></pre>
  <p>My app.component.html is:</p>
  <pre><code>&lt;app-header&gt;&lt;/app-header&gt;
  &lt;router-outlet&gt;&lt;/router-outlet&gt;
  </code></pre>
  <p>Concerning the app-routing.module.ts contains the routes which allow lazy loading:</p>
  <pre><code>const routes: Routes = [
    {
      path: WebsiteLanguage.English,
      loadChildren: () =&gt; import (&quot;./components/site/site.en.module&quot;).then(m =&gt; m.SiteEnModule)
    }, // lazy loading the English site module
    {
      path: WebsiteLanguage.French,
      loadChildren: () =&gt; import (&quot;./components/site/site.fr.module&quot;).then(m =&gt; m.SiteFrModule)
    },   // lazy loading the Czech site module
  
    {path: '**', redirectTo: WebsiteLanguage.English},  // redirecting to default route in case of any other prefix
  ];
  </code></pre>
  <p>If we have a look at the site.fr.module :</p>
  <pre><code>@NgModule({
    declarations: [],
    imports: [
      // CommonModule,
      SiteModule,
    ],
    providers: [
      // providing the value of english translation data
      {provide: TRANSLATION, useValue: fr},
    ],
  })
  export class SiteFrModule { }
  </code></pre>
  <p>Finally my SiteModule is simple:</p>
  <pre><code>@NgModule({
    declarations: [],
    imports: [
      CommonModule,
      SiteRoutingModule,
      // RouterModule
    ],
    exports: [
      CommonModule,
    ],
  })
  export class SiteModule { }
  </code></pre>
  <p>In my site.component html :</p>
  <pre><code>&lt;ol&gt;
    &lt;li *ngFor=&quot;let translation of translations&quot;&gt;
      &lt;a [routerLink]=&quot;['/', translation[1]]&quot;&gt;{{translation[0]}} ({{translation[1]}})&lt;/a&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
  
  &lt;!-- simple navigation links to switch between two &quot;translated&quot; views --&gt;
  &lt;a routerLink=&quot;home&quot;&gt;home&lt;/a&gt;
  &lt;a routerLink=&quot;info&quot;&gt;info&lt;/a&gt;
  </code></pre>
  <p>And my SiteComponent is injecting the translation:</p>
  <pre><code>export class SiteComponent implements OnInit {
  
    // this will extract tuple of translation key and name from enum
    translations = Object.entries(WebsiteLanguage);
  
    constructor(@Inject(TRANSLATION) public readonly lang: Translation) {
      // just a simple log to demonstrate usage in component class
      console.log('current language is', lang.language);
    }
  
    ngOnInit(): void {
    }
  }
  </code></pre>
  <p>I can navigate easily and change the language in the url and i have the correct translations.
  Now, my issue is that I have a menu which is in app.component.html.
  I could have used built in i18n tools in angular but i wanted to use json object to set the different translated statics contents.</p>
  <p>I tried to create a header modules and the header routing.
  I replicate the code used for SiteComponent.</p>
  <p>For example my route have this definition:</p>
  <pre><code>const headerRoutes: Routes = [
    // loadChildren: './home/home.module#HomeModule'
    // loadChildren: './info/info.module#InfoModule'
    {
      path: '',
      component: HeaderComponent,
      children: [
        {
          path: 'home',
          loadChildren: () =&gt; import (&quot;../../site/home/home.module&quot;).then(m =&gt; m.HomeModule)
        },
        {
          path: 'info',
          loadChildren: () =&gt; import (&quot;../../site/info/info.module&quot;).then(m =&gt; m.InfoModule)
        },
        {
          path: '',
          pathMatch: 'full',
          redirectTo: 'home'
        },
      ],
    },
  ];
  
  @NgModule({
    imports: [RouterModule.forChild(headerRoutes)],
    exports: [RouterModule],
  })
  export class HeaderRoutingModule {}
  </code></pre>
  <p>My HTML :</p>
  <pre><code>&lt;a routerLink=&quot;home&quot;&gt;From file&lt;/a&gt; |
  &lt;a routerLink=&quot;info&quot;&gt;From server&lt;/a&gt;
  </code></pre>
  <p>I unfortunatelly obtain this error message:</p>
  <pre><code>core.js:6479 ERROR NullInjectorError: R3InjectorError(AppModule)[InjectionToken TRANSLATION -&gt; InjectionToken TRANSLATION -&gt; InjectionToken TRANSLATION]: 
    NullInjectorError: No provider for InjectionToken TRANSLATION!
      at NullInjector.get (core.js:11101)
      at R3Injector.get (core.js:11268)
      at R3Injector.get (core.js:11268)
      at R3Injector.get (core.js:11268)
      at NgModuleRef$1.get (core.js:25332)
      at Object.get (core.js:25046)
      at lookupTokenUsingModuleInjector (core.js:3342)
      at getOrCreateInjectable (core.js:3454)
      at Module.ɵɵdirectiveInject (core.js:14737)
  </code></pre>
  <p>By commenting the following lines in my header.component.ts file:</p>
  <pre><code>// constructor(@Inject(TRANSLATION) public readonly lang: Translation) {
  //   // just a simple log to demonstrate usage in component class
  //   console.log('current language is', lang.language);
  // }
  </code></pre>
  <p>the page is displayed, the site component is translating the content based on the translation file.</p>
  <p>I have 2 issues:</p>
  <ul>
  <li>how can i inject the TRANSLATION without breaking all the application ?</li>
  </ul>