title: How to get Angular2+ Router working on a Angular2+/AngularJS hybrid application?
body: <p>How to get Angular2+ Router working on a Angular2+/AngularJS hybrid application?</p>
  
  <p>I'm working through <strong>Angular's upgrade</strong> guide to learn how to <strong>embed AngularJS directives in an Angular app</strong>. I've created a bare-bones Angular app using the Angular CLI and added a pretty simple AngularJS module as a dependency.</p>
  
  <p>Since I've added a <strong>RouterModule</strong> to Angular, I have the following error:</p>
  
  <pre><code>ERROR Error: Uncaught (in promise): Error: Trying to get the AngularJS injector before it being set.
  
      Router Event: NavigationError
          NavigationError(id: 1, url: '/', error: Error: Trying to get the AngularJS injector before it being set.)
              NavigationError {id: 1, url: "/", error: Error: Trying to get the AngularJS injector before it being set.
                  at injectorFactory (http://loca…}
  </code></pre>
  
  <p>My guess is that the problem comes from the fact that I'm displaying some Upgraded Directive inside the Angular <code>&lt;router-link&gt;</code></p>
  
  <p>Here's how I'm upgrading my AngularJS component inside my Angular app:</p>
  
  <pre><code>// ng1.component.wrapper.ts
  import { Directive, ElementRef, Injector, Input } from '@angular/core';
  import { UpgradeComponent } from '@angular/upgrade/static';
  
  @Directive({ selector: 'ng1' })
  export class Ng1ComponentWrapper extends UpgradeComponent {
      @Input() value1: string;
      @Input() value2: string;
  
      constructor(elementRef: ElementRef, injector: Injector) {
          super('ng1', elementRef, injector);
      }
  }
  </code></pre>
  
  <p>And here's my <code>app.module.ts</code>:</p>
  
  <pre><code>// app.module.ts
  
  // Import AngularJS app
  import '../ng1/ng1.module';
  
  import { BrowserModule } from '@angular/platform-browser';
  import { NgModule } from '@angular/core';
  import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static';
  
  import { AppRoutingModule } from './app-routing.module';
  
  import { AppComponent } from './app.component';
  
  // -----------------------------
  // ---- Upgraded components ----
  // -----------------------------
  import { Ng1ComponentWrapper } from '../ng1/ng1.component.wrapper';
  
  // -----------------------------
  // ---- Downgrade components ----
  // -----------------------------
  import { NG1_APP_MODULE_NAME } from '../ng1/ng1.module';
  declare var angular: any;
  
  angular.module(NG1_APP_MODULE_NAME)
      .directive('appRoot', downgradeComponent({ component: AppComponent }))
  
  @NgModule({
      declarations: [
          AppComponent,
          Ng1ComponentWrapper
      ],
      imports: [
          AppRoutingModule,
          BrowserModule,
          UpgradeModule,
      ],
      providers: [],
      bootstrap: [ AppComponent ],
  })
  export class AppModule {
      constructor(public upgrade: UpgradeModule) {}
  }
  </code></pre>
  
  <p>And here is the <code>main.ts</code> file where I bootstrap both Angular and AngularJS app</p>
  
  <pre><code>import { enableProdMode } from '@angular/core';
  import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
  
  import { AppModule } from './app/app.module';
  import { environment } from './environments/environment';
  
  import { NG1_APP_MODULE_NAME } from './ng1/ng1.module';
  import { setUpLocationSync } from '@angular/router/upgrade';
  
  if (environment.production) {
      enableProdMode();
  }
  
  
  // This is the entry point for the AngularJS/Angular hybrid application.
  // It bootstraps the Angular module 'AppModule', which in turn bootstraps
  // the AngularJS module.
  platformBrowserDynamic().bootstrapModule(AppModule)
      .then(ref =&gt; {
          console.log('Angular app bootstrapped !')
          const upgrade = (&lt;any&gt;ref.instance).upgrade;
          upgrade.bootstrap(document.body, [NG1_APP_MODULE_NAME]);
          console.log('AngularJS app bootstrapped !');
          setUpLocationSync(upgrade);
      })
      .catch(err =&gt; console.error('An error occured while bootstrapping the Angular app', err));
  </code></pre>
  
  <p>Here is the main AngularJS module file <code>ng1.module.ts</code></p>
  
  <pre><code>'use strict';
  
  import 'angular';
  
  import 'xcomponent-widgets/common-module';
  import { Ng1Component } from './ng1.component';
  
  export const NG1_APP_MODULE_NAME = 'test-webapp';
  
  declare var angular: any;
  
  angular.module(NG1_APP_MODULE_NAME, [
      'common-module'
  ])
  .config(['$locationProvider', ($locationProvider) =&gt; {
      $locationProvider.html5Mode(true);
  }])
  .component('ng1', Ng1Component);
  </code></pre>
  
  <p>And finally here is my router </p>
  
  <pre><code>import { NgModule } from '@angular/core';
  import { RouterModule, Routes } from '@angular/router';
  
  import { Ng1Component } from './component/ng1.component.ts';
  
  export const appRoutes: Routes = [
      {
          path: 'test',
          component: Ng1ComponentWrapper,
          data: { title: 'Test' }
      },
      { path: 'not-found', component: NotFoundComponent },
      { path: '', redirectTo: 'test', pathMatch: 'full' }, // Redirect to homepage by default
      { path: '**', redirectTo: 'not-found', pathMatch: 'full' } // If no route defined, redirect to page not found
  ];
  
  @NgModule({
      imports: [ RouterModule.forRoot(appRoutes, { enableTracing: true, useHash: false }) ],
      exports: [ RouterModule ]
  })
  export class AppRoutingModule {}
  </code></pre>
  
  <p><code>Ng1Component</code> uses an upgraded directive from <code>Ng1ComponentWrapper</code></p>
  
  <p>I'm using Angular 7.1.4 and AngularJS 1.6.4</p>