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

StaticInjectionError for service after migrating to Angular 5. // Solution: --preserve-symlinks #299

Closed
cathy02 opened this issue Nov 20, 2017 · 21 comments

Comments

@cathy02
Copy link

cathy02 commented Nov 20, 2017

Type of Issue

Service package error after migrate to Angular 5

[x] Bug Report
[ ] Feature Request


## Description

I have an Angular CLI generated project that just has only one service file my-test.service.ts

@Injectable()
export class MyTestService {
   ......
}

I publish it to NPM using ng-packagr. I can use the package in my other projects before migrating to Angular 5. After migration, I got error:
 
ERROR Error: StaticInjectorError[MyTestService]: 
  StaticInjectorError[MyTestService]: 
    NullInjectorError: No provider for MyTestService!
    at _NullInjector.get (core.js:923)
    at resolveToken (core.js:1211)
    at tryResolveToken (core.js:1153)
    at StaticInjector.get (core.js:1024)
    at resolveToken (core.js:1211)
    at tryResolveToken (core.js:1153)
    at StaticInjector.get (core.js:1024)
    at resolveNgModuleDep (core.js:10585)
    at NgModuleRef_.get (core.js:11806)
    at resolveDep (core.js:12302)

#### How To Reproduce



#### Expected Behaviour



#### Version Information

ng-packagr: v1.6.0
node: v8.x.y
@angular: v5.0.0
rxjs:
zone.js:


_please include any version information that might be relevant, e.g. other third-party libraries_
@oliveti
Copy link

oliveti commented Nov 20, 2017

I've got the same issue in my project.

@cathy02
Copy link
Author

cathy02 commented Nov 20, 2017

It turns out the problem is from another component module in my project. The module MyNavbarModule has a dependency on MyTestService. I have to add MyTestService to MyNavbarModule's providiers in addition to add it in the AppModule's providers. Then the error will go away. But I don't think it is correct since there will have two instances of the MyTestService in my application. Right?

When I test MyNavbarModule independently, I don't need to add MyTestService to MyNavbarModule's providers. Only when I package the module as NPM package and to use it in another project I need to do this. Also when using Angular 4.2.4, I DO NOT need to do it.

@dherges
Copy link
Contributor

dherges commented Nov 25, 2017

Hi @cathy02 @oliveti

For Angular v5, please use the 2.0.0 release candidates! Make sure you have a typescript version that is supported by Angular, i.e. "~2.4.x" for angular v5. Should the error still exist, please provide a reproduction, e.g. a GitHub repo.

For Angular v4, please use the 1.x version as it has the peerDependency on TypeScript 2.3.x which is recommended/supporter for Angular 4.

@oliveti
Copy link

oliveti commented Nov 25, 2017

hi @dherges,

Thank you for your hint. I tried the latest rc and I still have the same issue :

core.js:1350 ERROR Error: Uncaught (in promise): Error: StaticInjectorError[InjectionToken FirebaseAppConfigToken]: StaticInjectorError[InjectionToken FirebaseAppConfigToken]: NullInjectorError: No provider for InjectionToken FirebaseAppConfigToken!

I will try to create a github repo with reproduction of the issue.

@DavidParks8
Copy link
Member

I’m pretty sure I know what’s wrong, but I’d like that reproduction repo before I say anything (just to be sure).

@Elecash
Copy link

Elecash commented Nov 27, 2017

@dherges I have the same problem with v2.0.0-rc.3.

You can try it on this branch https://github.com/videogular/videogular2/tree/migration/angular5

Build first Core and then Controls. It works on compilation time but on execution time it throws this error:

Error: StaticInjectorError[VgFullscreenAPI]: 
  StaticInjectorError[VgFullscreenAPI]: 
    NullInjectorError: No provider for VgFullscreenAPI!
    at _NullInjector.get (core.js:923)
    at resolveToken (core.js:1211)
    at tryResolveToken (core.js:1153)
    at StaticInjector.get (core.js:1024)
    at resolveToken (core.js:1211)
    at tryResolveToken (core.js:1153)
    at StaticInjector.get (core.js:1024)
    at resolveNgModuleDep (core.js:10585)
    at NgModuleRef_.get (core.js:11806)
    at resolveDep (core.js:12302)

BTW, this tool is amazing, thank you for the great job! 👍

@dherges
Copy link
Contributor

dherges commented Nov 27, 2017

Hi @Elecash,

thank you! good!

VgFullscreenAPI = __decorate$4([
    Injectable(),
    __metadata$2("design:paramtypes", [])
], VgFullscreenAPI);

https://github.com/videogular/videogular2/blob/migration/angular5/build/controls/dist/%40videogular/controls.js#L529-L532

Compared to a working example:

IconRegistry = __decorate$15([
    Injectable(),
    __metadata$9("design:paramtypes", [HttpClient])
], IconRegistry);

The __decorate() and __metadata() helpers from tslib were duplicated since ever long ago (and should not MUST NOT cause any issue).

Why is the controls.js in ECMAScript 5 Syntax?!?

The VgFullscreenApi is then injected into a component:

VgPlayer = __decorate$1$1([
    Component({
        selector: 'vg-player',
        encapsulation: ViewEncapsulation.None,
        template: "\n      <ng-content></ng-content>\n    ",
        styles: ["\n      vg-player {\n        font-family: 'videogular';\n        position: relative;\n        display: flex;\n        width: 100%;\n        height: 100%;\n        overflow: hidden;\n        background-color: black; }\n        vg-player.fullscreen {\n          position: fixed;\n          left: 0;\n          top: 0; }\n        vg-player.native-fullscreen.controls-hidden {\n          cursor: none; }\n    "],
        providers: [VgAPI, VgFullscreenAPI, VgControlsHidden]
    }),
    __metadata$1$1("design:paramtypes", [ElementRef, VgAPI, VgFullscreenAPI, VgControlsHidden])
], VgPlayer);

... and exposed as provider in VgCoreModule:

VgCoreModule = __decorate$2$1([
    NgModule({
        imports: [CommonModule],
        declarations: [CORE_DECLARATIONS],
        exports: [CORE_DECLARATIONS],
        providers: [VgAPI, VgFullscreenAPI, VgUtils, VgControlsHidden]
    })
], VgCoreModule);

compared to the working example where the difference is that the provider is declared in a .forRoot():

IconComponent = __decorate$16([
    Component({
        template: "\n    <ng-content></ng-content>\n  ",
        changeDetection: ChangeDetectionStrategy.OnPush
    }),
    __metadata$10("design:paramtypes", [ChangeDetectorRef,
        ElementRef,
        Renderer,
        ViewContainerRef,
        IconRegistry])
], IconComponent);

var IconModule = IconModule_1 = (function () {
    function IconModule() {
    }
    IconModule.forRoot = function () {
        return {
            ngModule: IconModule_1,
            providers: [
                IconRegistry
            ]
        };
    };
    return IconModule;
}());
IconModule = IconModule_1 = __decorate$17([
    NgModule({
        imports: [
            CommonModule
        ],
        declarations: [ IconComponent ],
        exports:  [ IconComponent ]
    })
], IconModule);
var IconModule_1;

@dherges
Copy link
Contributor

dherges commented Nov 27, 2017

VgFullscreenApi is NOT exposed in the public_api.ts, rightThere's noexport { ... }` in the generated bundle index

https://github.com/videogular/videogular2/blob/migration/angular5/build/controls/dist/%40videogular/controls.js#L4371


This is different to the examples I have, where those services are exposed in the public_api.ts and thus an export { } is added to the generated bundle index:

export { /* .. */ IconRegistry, IconComponent, IconModule,/* .. */ };

@Elecash
Copy link

Elecash commented Nov 27, 2017

@dherges yes, I have to do some changes forRoot() is indeed one of them.

I will review your suggestions but I think that I can make it work.

Thank you!

@dherges
Copy link
Contributor

dherges commented Nov 27, 2017

Hi @Elecash,

let's see if we can find iut the cause for the StaticInjection error message. The only difference I see is that the service is not explicitly exported in public_api.ts so I am quite surprised.

Checked then the AoT control.metadata.json. This is generated for the constructor parameters of dependent components in the controls package:

{"__symbolic":"reference","module":"@videogular/core","name":"VgFullscreenAPI"}

So that should be good to look up the injectable from node_modules/@videogular/core ... If someone finds out what is going wrong ... ☀️

@dherges
Copy link
Contributor

dherges commented Nov 29, 2017

Hi @cathy02 @oliveti @Elecash ,

the error is reproducible in the integration tests of ng-packagr by running ng serve in the Angular CLI consumer app.

If any of you can figure out what is causing the Angular DI to throw the StaticInjectionError, it's going to help!

@dherges dherges mentioned this issue Nov 29, 2017
8 tasks
@jcjolley
Copy link

jcjolley commented Dec 5, 2017

Any progress on this? I have a lib working on an angular 5 project that's been ejected from the angular/cli, but am still running into StaticINjectionError[Router] on a separate project that is using the angular/cli.

EDIT: After doing the following steps, the library started working in the Angular CLI consumer app

  1. Create a new project with the Angular CLI.
  2. Copy over all of the dependencies from its package.json to the package.json of your consumer app.
  3. Delete the node_modules folder and package-lock.json in your consumer app.
  4. npm install in your consumer app

@dherges
Copy link
Contributor

dherges commented Dec 6, 2017

See #335 (comment) : preserveSymlinks may help

@aryanisml
Copy link

aryanisml commented Jan 23, 2018

Still facing the issue Uncaught (in promise): Error: StaticInjectorError Any solution on it.

Using Angular cli 1.5.4 and Angular 5.0.0
Created the service library which contained the httpclient.post() call and create the package using ng-packager.
In consumer app added the service library package using npm.

On run time when we run the application it throw the error
Uncaught (in promise): Error: StaticInjectorError
No provider for httpclient

If we tested the service library code without consuming in any application it work as expected.
when we consumed in any application and run that application it throw the run time error

Also try preserveSymlinks in angular.cli.json file in consumer application however no success still the error present run time.
"defaults": {
"styleExt": "css",
"build": {
"preserveSymlinks": true
},
"component": {}
}
***Service code application name - CommonApp

test.service.ts simply added the httpClient in constructor,

@Injectable()
export class TestService {

constructor(private httpClient: HttpClient) { }
getData(){
    return 'Hello World';
}

}

The issue is resolved Updated angular cli and added
"build": {
"preserveSymlinks": true
},
It's working now.

@dherges dherges changed the title StaticInjectionError for service after migrating to Angular 5. StaticInjectionError for service after migrating to Angular 5. // Solution: --preserve-symlinks Jan 25, 2018
@dherges dherges added documentation and removed bug labels Jan 25, 2018
@dherges dherges closed this as completed Jan 25, 2018
@trollkotze
Copy link

Why is this closed? It seems it is not fixed, or is it?
I see neither a fix nor a clear explanation.

@miloszsobczak
Copy link

"build": {
"preserveSymlinks": true
},

Above solution works, but I assume it's workaround.

@kolbma
Copy link

kolbma commented Apr 13, 2018

I've set preserveSymlinks and I'm running into this with

ng-packagr:            2.4.2  
@angular/compiler:     5.2.9  
@angular/compiler-cli: 5.2.9  
rollup:                0.55.5  
tsickle:               0.27.5  
typescript:            2.6.2  

Angular CLI: 6.0.0-rc.4
Node: 8.11.1
OS: win32 x64
Angular: 5.2.9
... animations, common, compiler, compiler-cli, core
... platform-browser, platform-browser-dynamic

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.5.6
@angular-devkit/core         0.5.6
@angular-devkit/schematics   0.5.6
@angular/cli                 6.0.0-rc.4
@ngtools/json-schema         1.1.0
@schematics/angular          0.5.6
@schematics/update           0.5.6
rxjs                         5.5.10
typescript                   2.6.2

My ng-packagr run looks like this:

Building Angular Package
Building entry point 'n4v-privacy-sidebar'
Cleaning build directory
Rendering Stylesheets
Rendering Templates
Compiling TypeScript sources through ngc
Bundling to FESM15
Bundling to FESM5
Bundling to UMD
No name was provided for external module 'primeng/sidebar' in options.globals – guessing 'sidebar'
Minifying UMD bundle
Relocating source maps
Copying staged files
Writing package metadata
Removing scripts section in package.json as it's considered a potential security vulnerability.
Creating package .tgz
Built n4v-privacy-sidebar
Built Angular Package!
- from: C:\Users\makolb\Source\Repos\angular\primeng\privacy-sidebar
- to:   C:\Users\makolb\Source\Repos\angular\primeng\privacy-sidebar\dist

When I start up ng serv -watch:

** Angular Live Development Server is listening on localhost: 4200, open your browser on http://localhost:4200/ **

Date: 2018-04-13T19:16:43.605Z
Hash: 7a50f7e5fe65eb5a80c3
Time: 33661ms
chunk {main} main.js, main.js.map (main) 19.1 kB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 223 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 5.09 kB [entry] [rendered]
chunk {styles} styles.js, styles.js.map (styles) 387 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 4.89 MB [initial] [rendered]

WARNING in ../angular/primeng/privacy-sidebar/node_modules/@angular/core/esm5/core.js
6558:15-36 Critical dependency: the request of a dependency is an expression

WARNING in ../angular/primeng/privacy-sidebar/node_modules/@angular/core/esm5/core.js
6578:15-102 Critical dependency: the request of a dependency is an expression
i 「wdm」: Compiled with warnings.

And in browser:

PrivacySidebarComponent.html:2 ERROR Error: StaticInjectorError(AppModule)[NgClass -> ElementRef]: 
  StaticInjectorError(Platform: core)[NgClass -> ElementRef]: 
    NullInjectorError: No provider for ElementRef!
    at _NullInjector.push../node_modules/@angular/core/esm5/core.js._NullInjector.get (core.js:1002)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1242)
    at StaticInjector.push../node_modules/@angular/core/esm5/core.js.StaticInjector.get (core.js:1110)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1242)
    at StaticInjector.push../node_modules/@angular/core/esm5/core.js.StaticInjector.get (core.js:1110)
    at resolveNgModuleDep (core.js:10854)
    at NgModuleRef_.push../node_modules/@angular/core/esm5/core.js.NgModuleRef_.get (core.js:12087)
    at resolveDep (core.js:12577)

@kolbma
Copy link

kolbma commented Apr 13, 2018

@dherges should this really be closed?

@remborg
Copy link

remborg commented Apr 19, 2018

I had the same issue and I've spent a full day trying to fix it. Deleting the package-lock.json file made it work. Thanks @jcjolley for this!

@subhankars-canvas
Copy link

LOL I went through the comments actually no damn one gave a particular solution, man just put your service class in your app.moudule.ts' providers array , you forgot that only , happy coding ❤️

@github-actions
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

This action has been performed automatically by a bot.

@github-actions github-actions bot locked and limited conversation to collaborators Jun 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests