Search code examples
angularjsangular-ui-routerng-upgrade

@angular/router not working inside an angular.js application


I'm working on migrating little by little a big angular.js application (that uses ui-router) to angular and I opted by using the angular.js application as a base and migrate the different routes one at a time so that once I'm finished I switch everything at once to angular.

These are the steps I've followed:

Bootstap the angular.js application in my main.ts file:

export function bootstrapAngular(extra: StaticProvider[]): any {
  setAngularJSGlobal(angular);
  if (environment.production) {
    enableProdMode();
  }
  return platformBrowserDynamic(extra)
    .bootstrapModule(AppModule)
    .catch(err => console.log(err));
}

const downgraded = angular
  .module('downgraded', [downgradeModule(bootstrapAngular)])
  .directive('appRoot', downgradeComponent({ component: RootComponent, propagateDigest: false }))
  ;

angular.bootstrap(document, ['app', downgraded.name]);

Inside my index.html

<app id="app"></app>

This works fine.

Inside my main angular.js component I add the tag of my downgraded main Angular component:

<div class="app__view" id="appContent">
  <ui-view></ui-view>
  <app-root></app-root>
</div>

This is how my main module is configured

const COMPONENTS = [
  TestComponent,
  RootComponent,
];

@NgModule({
  declarations: COMPONENTS,
  imports: [
    BrowserModule,
    NxModule.forRoot(),
    RouterModule.forRoot(routes, {
      initialNavigation: 'enabled',
      useHash: true
    })
  ],
  providers: [
    { provide: APP_BASE_HREF, useValue: '/' }
  ],
  entryComponents: COMPONENTS,
  exports: COMPONENTS
})
export class AppModule {
  ngDoBootstrap(): void { }
}

Everything works fine so far. I can see my angular component inside my angular.js application.

The problem comes when I add the to my main root component I can see the router-outlet rendering but nothin next to it, eventhough the route matches.

export const routes: Route[] = [
  { path: 'dashboard', component: TestComponent }
];

When I point my browser to /#/dashboard this is the router tracing that I see:

router tracing

And the test component just doesn't render.

enter image description here

I need some help, can't think of anything else to try.


Solution

  • The solution involved:

    • Getting rid of UrlHandlingStrategy completely
    • Disabling initialNavigation
    • Creating empty routes in both route configurations
    • Injecting the ng2 router in the ng1 application and adding the following logic

      angular.module('app').config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
        $stateProvider.state('ng2', { });
      
        $urlRouterProvider.otherwise(($injector, $location) => {
          const $state = $injector.get('$state');
          const ng2Routes = ['dashboard'];
          const ng2Router = $injector.get('ng2Router');
          const url = $location.url();
          if (ng2Routes.some(feature => url.startsWith('/' + feature))) {
            $state.go('ng2');
            ng2Router.navigate([url]);
          } else {
            $state.go('messages');
          }
        });
      }]);