angular-hybrid icon indicating copy to clipboard operation
angular-hybrid copied to clipboard

State `resolve` parameters don't work with dependencies when using `downgradeModule`

Open llRandom opened this issue 4 years ago • 1 comments

Adding any dependency to resolve parameters of route definitions causes the following error: Trying to get the Angular injector before bootstrapping the corresponding Angular module. This only happens when bootstrapping the app with downgradeModule.

Steps to reproduce:

  1. Clone https://github.com/ui-router/angular-hybrid/tree/master/example
  2. Replace main.ts with the following content:
import * as angular from 'angular';
import { Component, NgModule } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { UpgradeModule, downgradeModule } from '@angular/upgrade/static';
import { BrowserModule } from '@angular/platform-browser';
import { UIRouterUpgradeModule, NgHybridStateDeclaration } from '@uirouter/angular-hybrid';

const app = angular.module('minimal', ['ui.router.upgrade']);

app.config($stateProvider => {

  $stateProvider.state('app', {
    url: '',
    template: `
        <a ui-sref=".ng1" ui-sref-active-eq="active">app.ng1</a>
        <a ui-sref=".ng1.ng2" ui-sref-active-eq="active">app.ng1.ng2</a>
        <a ui-sref=".ng2" ui-sref-active-eq="active">app.ng2</a>
        <a ui-sref=".ng2.ng2" ui-sref-active-eq="active">app.ng2.ng2</a>
        <ui-view></ui-view>
      `,
  });

  // route to ng1 component
  $stateProvider.state('app.ng1', {
    url: '/ng1',
    component: 'ng1Component',
    resolve: {
      // adding any dependency causes the error
      test123: function($q) {
        return { test: 123 };
      }
    }
  });

  // nested route to ng2 component
  $stateProvider.state('app.ng1.ng2', {
    url: '/ng2',
    component: Ng2Component,
  });

  // route to ng2 component
  $stateProvider.state('app.ng2', {
    url: '/ng2',
    component: Ng2Component,
  });
})

app.run(($urlService) => {
  $urlService.rules.initial({ state: 'app' });
});

// An AngularJS component
app.component('ng1Component', {
  template: `
      <h1>ng1 component</h1>
      <a ui-sref="app">Back to app</a>
      <ui-view></ui-view>
    `,
  controller: function() {
    this.$onInit = function() {
      console.log('ng1Component.$onInit()');
    };
  },
});

// An Angular component
@Component({
  selector: 'ng2-component',
  template: `
      <h1>ng2 component</h1>
      <a uiSref="app">Back to app</a>
      <ui-view></ui-view>
    `,
})
export class Ng2Component {
  ngOnInit() {
    console.log('Ng2Component.ngOnInit()');
  }
}

const nestedState: NgHybridStateDeclaration = {
  url: '/ng2',
  name: 'app.ng2.ng2',
  component: Ng2Component,
};

// The root Angular module
@NgModule({
  imports: [
    BrowserModule,
    // Provide Angular upgrade capabilities
    UpgradeModule,
    // Provides the @uirouter/angular directives
    UIRouterUpgradeModule.forRoot({ states: [nestedState] }),
  ],
  declarations: [Ng2Component],
  entryComponents: [Ng2Component],
})
export class RootModule {
  ngDoBootstrap() { }
}

// Using AngularJS config block, call `deferIntercept()`.
// This tells UI-Router to delay the initial URL sync (until all bootstrapping is complete)
app.config(['$urlServiceProvider', $urlService => $urlService.deferIntercept()]);
angular.module('app-hybrid', ['minimal', downgradeModule(extraProviders => platformBrowserDynamic(extraProviders).bootstrapModule(RootModule))]);
const injector = angular.bootstrap(document, ['app-hybrid']);
const urlService: any = injector.get('$urlService');

setTimeout(() => {
    // setTimeout needed to allow angular routes to initialize after refresh
    urlService.listen();
    urlService.sync();
}, 1000);

It works fine if resolve doesn't have any dependencies.

llRandom avatar Mar 06 '20 15:03 llRandom

I'm also experiencing this issue but I'm not even using the hybrid router as I'm not attempting to route to upgraded components and all of my routes are defined in the angularjs context... but my angularjs ui router does have resolvers that needs to inject, and this is entirely broken if any service is downgraded with downgradeInjectable. Even if that service isn't needed by the router which is confusing to me.

Any insight on this at all?

bd60 avatar Apr 28 '20 18:04 bd60

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. This does not mean that the issue is invalid. Valid issues may be reopened. Thank you for your contributions.

stale[bot] avatar Nov 12 '22 11:11 stale[bot]