Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"No provider for UrlService" error since version 3.1.3 (Angular CLI based app in AOT mode) #53

Closed
adamlubek opened this issue Aug 18, 2017 · 18 comments

Comments

@adamlubek
Copy link

adamlubek commented Aug 18, 2017

I've got hybrid app based on Angular CLI. When running app in AOT mode (ng serve -o --aot=true) when this piece of code is run:

platformBrowserDynamic().bootstrapModule(AppModule)
  .then(platformRef => {
            const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
            upgrade.bootstrap(document.body, ['app'], {strictDi: false});

            const url: UrlService = platformRef.injector.get(UrlService);
            url.listen();
            url.sync();
    });

I am getting:
"Unhandled Promise rejection: No provider for UrlService! ; Zone: <root> ; Task: Promise.then ; Value: Error: No provider for UrlService!"

Both AOT/JIT version works fine with version 3.1.2. Version 3.1.3/3.1.4 works only in JIT mode.

@adamlubek adamlubek changed the title "No provider for UrlService" error in AOT mode since version 3.1.3 "No provider for UrlService" error since version 3.1.3 (Angular CLI based app in AOT mode) Aug 18, 2017
@leosun1221
Copy link

Remove angular-ui-router (or @uirouter/angularjs) from your package.json and replace it with @uirouter/angular-hybrid. Add the @angular/* dependencies.

I removed those two then working:
@uirouter/angular": "^1.0.0-beta.7"
@uirouter/angularjs": "^1.0.6"

@adamlubek
Copy link
Author

@leosun1221 I don't understand what you're talking about, Your comment seems incomplete. Which npm package do you mean by angular-ui-router? I've got @angular dependencies added, which exactly are you referencing? Also, I don't have any packages with versions you're referencing ("^1.0.0-beta.7", "^1.0.6").

Your comment isn't too helpful, can you clarify what you meant please?

@artaommahe
Copy link

@adamlubek also had this problem, this fixed my issue ui-router/sample-app-angular-hybrid#8 (comment)

@adamlubek
Copy link
Author

@artaommahe so I changed code from:

    const url: UrlService = platformRef.injector.get(UrlService);

    url.listen();
    url.sync();

to


    const url: UrlService = getUIRouter(platformRef.injector).urlService;;

    url.listen();
    url.sync();

this compiles indeed but it completely breaks routing, states which were working aren't recognized anymore

@artaommahe
Copy link

@adamlubek i use it like so

deferAndSyncUiRouter(AppMainOldModule);

platformBrowserDynamic()
  .bootstrapModule(AppMainModule)
  .then(platformRef => bootstrapWithUiRouter(platformRef, AppMainOldModule));

export function deferAndSyncUiRouter(angularjsModule: ng.IModule): void {
  angularjsModule
    .config([ "$urlServiceProvider", ($urlServiceProvider: UrlRouterProvider) => $urlServiceProvider.deferIntercept()])
    .run(["$$angularInjector", $$angularInjector => {
      const url: UrlService = getUIRouter($$angularInjector).urlService;
      url.listen();
      url.sync();
    }]);
}

export function bootstrapWithUiRouter(platformRef: NgModuleRef<any>, angularjsModule: ng.IModule): void {
  const injector = platformRef.injector;
  const upgradeModule = injector.get(UpgradeModule);

  upgradeModule.bootstrap(document.body, [ angularjsModule.name ], { strictDi: true });
}

@adamlubek
Copy link
Author

adamlubek commented Sep 20, 2017

I've tried your code @artaommahe , routes are still dead :( the only difference is that I've got "$urlServiceProvider: UrlService" instead of "$urlServiceProvider: UrlRouterProvider" as I don't know where to import UrlRouterProvider from?

I'm running @angular/* version 4.4.2 and angular/cli version 1.4.2 if it makes any difference.

@leosun1221
Copy link

leosun1221 commented Sep 22, 2017

@adamlubek remove 'uirouter/angular' and 'uirouter/angularjs' in your package.json file,
only use 'uirouter/angular-hybrid'

I found this is the working example : https://github.com/ui-router/sample-app-angular-hybrid/tree/e4b1144d5e3e3451f0f0cc640175bb7055294fdd you can try download and build it

@adamlubek
Copy link
Author

@leosun1221 I don't have 'uirouter/angular' and 'uirouter/angularjs' in my package.json at all.

@rdukeshier
Copy link

I had the same issue. Appears to be fixed in 3.1.7.

@christopherthielen
Copy link
Member

I had the same issue. Appears to be fixed in 3.1.7.

Hello all, is this still an issue or can I close this? If it is an issue, can somebody show me how to reproduce it?

@ghost
Copy link

ghost commented Dec 26, 2017

I think it was fixed some time ago, I don't face it anymore

@adamlubek
Copy link
Author

yes, it's all good now, thanks @christopherthielen

@httpete
Copy link

httpete commented Jan 25, 2018

If anyone else is hitting things like this, it has to do with getting the PRECISE dependencies from angular-hybrid. The only thing you want is angular-hybrid, somehow it was not getting uirouter/angularjs and it was causing it to break. I also see it is not working with the latest Angular 5.2, but for now Im going to settle down on 5.1

Unhandled Promise rejection: StaticInjectorError(RootModule)[UrlService]:
StaticInjectorError(Platform: core)[UrlService]:
NullInjectorError: No provider for UrlService! ; Zone: ; Task: Promise.then ; Value: Error: StaticInjectorError(RootModule)[UrlService]:
StaticInjectorError(Platform: core)[UrlService]:

@lamaan
Copy link

lamaan commented Feb 1, 2018

the example hybrid app works when updated to latest(5.2.3), but I still get this problem on the app I am trying to get working.

@httpete
Copy link

httpete commented Feb 9, 2018

There are complications when using npm linked file:.. local packages and Angular. I am finding that this webpack config fixes it. The key is the modules, it HAS to point all to the TOP node_modules, not a nested version.

`        resolve: {
            extensions: ['.ts', '.js'],
            modules: [
                path.resolve(path.join(__dirname, 'node_modules'))
            ],
            symlinks: true,
            mainFields: [
                "browser",
                "module",
                "main"
            ],
            alias: {

            }
        }

@AlexSwensen
Copy link

AlexSwensen commented Mar 12, 2018

@artaommahe that was a super helpful code snippet.

I modified it to the following:

angular.element(document).ready(() => {
  deferAndSyncUiRouter(angularJSAppModule); // angularjs module as a variable
  platformBrowserDynamic()
    // Manually bootstrap the Angular app
    .bootstrapModule(AppModule) // Angular module imported from app.module.ts
    .then(platformRef => bootstrapWithUiRouter(platformRef, angularJSAppModule));

});

export function deferAndSyncUiRouter(angularjsModule: ng.IModule): void {
  angularjsModule
    .config([ "$urlServiceProvider", ($urlService: UrlService) => $urlService.deferIntercept()])
    .run(["$$angularInjector", $$angularInjector => {
      const url: UrlService = getUIRouter($$angularInjector).urlService;
      url.listen();
      url.sync();
    }]);
}

export function bootstrapWithUiRouter(platformRef: NgModuleRef<any>, angularjsModule: ng.IModule): void {
  const injector = platformRef.injector;
  const upgradeModule = injector.get(UpgradeModule);

  upgradeModule.bootstrap(document.body, [ angularjsModule.name ]);
}

That got everything working for me.

Edit: Also you all may find these imports helpful for the top of your angularjs module file.

import * as angular from 'angular';
import {NgModuleRef} from "@angular/core";
import {getUIRouter} from '@uirouter/angular-hybrid';
import {UrlService} from '@uirouter/angular-hybrid/node_modules/@uirouter/angularjs'
import {UpgradeModule} from "@angular/upgrade/static";
import {platformBrowserDynamic} from "@angular/platform-browser-dynamic";
import {AppModule} from "./app.module";

@Jakobinec
Copy link

Jakobinec commented Dec 30, 2019

@AlexSwensen or @artaommahe
Could you tell me please what code should be in AppModule.ts file (Angular module). If I use there code from documentation

const nestedState: NgHybridStateDeclaration = {
  url: '/angularRoute',
  name: 'angularRoute',
  component: UrlTestComponent,
};

@NgModule({
  declarations: [
    UrlTestComponent,
    AngularDowngradeTestComponent
  ],
  exports: [ AngularDowngradeTestComponent ],
  entryComponents: [AngularDowngradeTestComponent],
  imports: [
    BrowserModule,
    UpgradeModule,
    // UIRouterUpgradeModule.forRoot(),
    //UIRouterUpgradeModule.forChild(StaticPagesRoutes)
    UIRouterUpgradeModule.forRoot({ states: [nestedState] }),
  ],
  providers: [],
})
export class AppModule 
{ 
  constructor(private upgrade: UpgradeModule) { }
  ngDoBootstrap() {
    setAngularJSGlobal(angular);
    this.upgrade.bootstrap(document.body, ['mainApp'], { strictDi: true });
  }
}

I have an error 'You try bootstrap application twise'. I think the problem is in
this.upgrade.bootstrap(document.body, ['mainApp'], { strictDi: true });

@christopherthielen
Copy link
Member

christopherthielen commented Dec 31, 2019

For anyone coming to this issue looking to resolve the "no provider" errors, make sure that you do not have multiple copies of the @uirouter/* packages nested in your node_modules directory.

One easy way to find out is to run these commands:

npm list @uirouter/core
npm list @uirouter/angular
npm list @uirouter/angularjs
npm list @uirouter/angular-hybrid

For each one, make sure there is only one version of the uirouter packages in the output.

good output

For example, for @uirouter/core only version 6.0.1 is listed in the output:

npm list @uirouter/core
sample-app-angular-hybrid@1.0.2 ~/projects/uirouter/sample-app-angular-hybrid
└─┬ @uirouter/angular-hybrid@9.0.0
  ├─┬ @uirouter/angular@5.0.0
  │ └── @uirouter/core@6.0.1  deduped
  ├─┬ @uirouter/angularjs@1.0.23
  │ └── @uirouter/core@6.0.1  deduped
  └── @uirouter/core@6.0.1

bad output

If there are multiple versions of a uirouter library, the output will look something like this:

npm list @uirouter/core
sample-app-angular-hybrid@1.0.2 ~/projects/uirouter/sample-app-angular-hybrid
├─┬ @uirouter/angular-hybrid@9.0.0
│ ├─┬ @uirouter/angular@5.0.0
│ │ └── @uirouter/core@6.0.1
│ ├─┬ @uirouter/angularjs@1.0.23
│ │ └── @uirouter/core@6.0.1
│ └── @uirouter/core@6.0.1
└── @uirouter/core@6.0.3

Note that versions 6.0.1 and 6.0.3 are both present


note: If you use yarn package manager, the command is yarn why @uirouter/core

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants