简体   繁体   中英

inject() must be called from an injection context

I am trying to export my Angular app as an npm module to be consumed by other applications, but am running into some difficulties. I have not been able to find this error anywhere else on the internet, and am at my wit's end.

I followed this tutorial: https://medium.com/@nikolasleblanc/building-an-angular-4-component-library-with-the-angular-cli-and-ng-packagr-53b2ade0701e

I used ng-packagr to export my app as an npm module. I can successfully install it from a local folder on a barebones test app, but cannot get it to display my app.

Error:

    AppComponent.html:1 ERROR Error: inject() must be called from an injection context
    at inject (core.js:1362)
    at ChangeStackService_Factory (template-wiz.js:2074)
    at _callFactory (core.js:8223)
    at _createProviderInstance (core.js:8181)
    at resolveNgModuleDep (core.js:8156)
    at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get (core.js:8849)
    at resolveDep (core.js:9214)
    at createClass (core.js:9094)
    at createDirectiveInstance (core.js:8971)
    at createViewNodes (core.js:10191)

template-wiz.module.ts (Module being exported)

    import { NgModule, ChangeDetectorRef, ComponentFactoryResolver } from '@angular/core';
    import { TemplateWizComponent } from './template-wiz.component';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms';
    import { HttpClientModule } from '@angular/common/http';
    import { BlockListDirective } from './Directives/block-list.directive';
    import { TemplateItemsDirective } from './Directives/template-items.directive';
    import { ContextMenuComponent, SeperatorComponent, DragBoxComponent, SnapLineComponent, PropertiesComponent, ToolboxComponent } from './Components'
    import { AddressBlockComponent, TextBlockComponent, ImageBlockComponent, DataBlockComponent } from './Data-Blocks';
    import { BlockFactoryService, BlockRegistryService, DisplayInfoService, MouseClickService, SavingService, SnapService, TextHelperService, UserModeService } from './Services';
    import { PageContextMenuComponent } from './Components/page-context-menu/page-context-menu.component';
    import { CamelToWordsPipe } from './Pipes/camel-to-words.pipe';
    import { PdfPublisherService } from './Services/pdf-publisher/pdf-publisher.service';
    import { GradientBlockComponent } from './Data-Blocks/gradient-block/gradient-block.component';
    import { PropToTypePipe } from './Pipes/prop-to-type.pipe';
    import { ShapeBlockComponent } from './Data-Blocks/shape-block/shape-block.component';
    import { CommonModule } from '@angular/common';
    import { ModuleWithProviders } from '@angular/compiler/src/core';


    @NgModule({
      imports: [
        CommonModule,
        FormsModule,
        HttpClientModule
      ],
      entryComponents: [
        AddressBlockComponent,
        ContextMenuComponent,
        DragBoxComponent,
        GradientBlockComponent,
        ImageBlockComponent,
        PageContextMenuComponent,
        SeperatorComponent,
        ShapeBlockComponent,
        SnapLineComponent,
        TextBlockComponent
      ],
      declarations: [
        TemplateWizComponent,
        DataBlockComponent,
        AddressBlockComponent,
        SeperatorComponent,
        BlockListDirective,
        TemplateItemsDirective,
        ImageBlockComponent,
        TextBlockComponent, DragBoxComponent,
        SnapLineComponent,
        ToolboxComponent,
        PropertiesComponent,
        ContextMenuComponent,
        PageContextMenuComponent,
        GradientBlockComponent,
        CamelToWordsPipe,
        PropToTypePipe,
        ShapeBlockComponent
      ],
      providers: [
        BlockFactoryService,
        BlockRegistryService,
        DisplayInfoService,
        MouseClickService,
        SavingService,
        SnapService,
        TextHelperService,
        UserModeService,
        PdfPublisherService
      ],
      //bootstrap: [TemplateWizComponent],
      exports: [
        TemplateWizComponent
      ]
    })
    export class TemplateWizModule {
      static forRoot(): ModuleWithProviders {
        return {
          ngModule: TemplateWizModule,
          providers: [
            ComponentFactoryResolver
          ]
        }
      }
    }

app.module.ts (Bare bones test app using my module)

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { FormsModule } from '@angular/forms';
    import { HttpClientModule } from '@angular/common/http';
    import { AppComponent } from './app.component';
    import { TemplateWizModule } from 'template-wiz';

    @NgModule({
      declarations: [
        AppComponent,
      ],
      imports: [
        BrowserModule,
        FormsModule,
        TemplateWizModule.forRoot(),
        HttpClientModule
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

Any help or pointers at all would be appreciated, thank you.

seems like an issue when using npm link when consuming the library.

Check out the following issue: https://github.com/angular/angular/issues/25813

Spoiler: use "projects.$name.architect.build.options.preserveSymlinks: true" in angular.json

I had the same error.

I found that I was importing Inject from @angular/core instead of @angular/core/testing .

Hope that helps!

Here's what solved it for me :

Add the following line in tsconfig.app.json under compilerOptions :

"paths": { "@angular/*": [ "../node_modules/@angular/*" ] }

Source : https://github.com/angular/angular/issues/25813#issuecomment-500091900

I ran in a similar problem. Using a angular lib within an angular app with npm link.

As mentioned: "Solution: use projects.$name.architect.build.options.preserveSymlinks: true in the angular.json file of the client project, not the library." works when serving the appliction with "ng serve".

However the error still was there when unit testing the application with "ng test". Adding preserveSymLinks in the the angular.json file here:

projects.$name.architect.test.options.preserveSymlinks: true

fixed that as well.

I got the error message inject() must be called from an injection context when I was creating a tree-shakable InjectionToken that used another InjectionToken in its factory, eg

import { InjectionToken } from '@angular/core';

import { dependeeToken } from './dependee.token';

export const dependingToken = new InjectionToken<string>('depending', {
  factory: () => inject(dependeeToken) + ' depending';
  providedIn: 'root',
});

Instead, I added a provider for the depending InjectionToken to an NgModule .

import { NgModule } from '@angular/core';

import { dependeeToken } from './dependee.token';
import { dependingToken } from './depending.token';

@NgModule({
  providers: [
    {
      deps: [dependeeToken],
      provide: dependingToken,
      useFactory: dependee => dependee + ' depending',
    }
  ],
})
export class DependingModule {}

package.json excerpt

{
  "dependencies": {
    "@angular/compiler": "6.1.9",
    "@angular/core": "6.1.9"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "0.8.4",
    "@angular/cli": "6.2.4",
    "@angular/compiler-cli": "6.1.9",
    "typescript": "2.9.2"
  }
}

What solved it for me was to use the providedIn property in the Injectable decorator instead of registering the service in the app module in the providers for the service which was causing me this error message.

@Injectable({
  providedIn: 'root'
})
export class HeroService {}

Same issue here

My Case: When I was using Mat Dialog

import { Component, OnInit, Inject } from '@angular/core';

 constructor(
    @Inject(MAT_DIALOG_DATA) public data: any,
    public matDialogRef: MatDialogRef<MatConfirmDialogComponent>) { }

inject & Inject are different:

inject is a function and Inject is Interface

I hope this helps someone who comes finding the same scenario.

Same issue but my case was dumber...

I had npm install something in the wrong folder.

So just rm the wrong "node_modules" and npm install in the good folder x)

I had this error when building angular 9.0.0-next.0 with ng build --prod command. Downgrading to version ~8.2.8 made my angular app work again.

It was working well in development with ng serve , so it seems to be linked to Ivy.

如果 Karma 测试出现错误,只需删除 de node_modules文件夹并重新安装。

I came across a similar problem in testing an Angular application. The application imported a Service that had been installed from @bit with npm. The service depended on the MatSnackBar which seemed to be causing the same error as the OP.

To get the tests to run I instantiated the service when configuring the testing module.

In the example below, the AsyncUIFeedbackService was installed from Bit via npm. Setting the useValue to a new instance of the service, and stubbing the MatSnackBar worked great.

await TestBed.configureTestingModule({
      declarations: [GeneralInfoComponent],
      providers: [
        FormBuilder,
        { provide : AsyncUIFeedbackService, 
          useValue: new AsyncUIFeedbackService({} as MatSnackBar)}, // <----Create the service
      ],
      imports: [AsyncUIFeedbackModule]
    }).compileComponents();

我发现我是从 @angular/core 导入 Inject 而不是 @angular/core/testing。

I my case it was because this code was missing in `test-setup.ts`. I had only the first 2 lines.
 
 
 
  
  import 'jest-extended'; import 'jest-preset-angular/setup-jest'; import { getTestBed } from '@angular/core/testing'; import { BrowserDynamicTestingModule, platformBrowserDynamicTesting, } from '@angular/platform-browser-dynamic/testing'; getTestBed().resetTestEnvironment(); getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), { teardown: { destroyAfterEach: false }, });
 
 

What made it a bit difficult was that I got a different unhelpul error even after adding this code because it was an Angular library package with its own package.json where the dependency @angular/platform-browser-dynamic was missing.

Above helped, but I removed this code again.
What actually helped was https://stackoverflow.com/a/68718393/217408

A publishable package

  • must not have dependencies , only peerDependencies
  • npm install should not be run. The library must not contain a node_modules directory.

Having dependencies and node_modules worked fine since months, but suddenly started failing and now even older commits don't work anymore without fixing above points.

For everyone that runs into this problem and uses Angular Universal and a custom Angular Library linked with npm link:

The mentioned solution to add preserveSymlinks to your angular.json projects.$name.architect.build.options.preserveSymlinks: true is missing two parts.

For dev:ssr or serve:ssr to work, you need to add it aditionaly here: projects.$name.architect.server.options.preserveSymlinks: true

And as mentioned in another comment, If you use tests, don't forget it here: projects.$name.architect.test.options.preserveSymlinks: true

If there is yet another use case / location not listed here, comment it below.

Update 2022

I was facing this problem in a Angular Library workspace. My directory structure looks like this

project
│   package.json
│
└───projects
│   │
│   └─── myLibApp
│       │   file111.txt
│       │   file112.txt
│       │   ...
│   
└─────── myLibExampleApp

I wanted to add some dependencies to my main library and I did npm i inside the myLibApp folder caused this problem. I had to remove the node_modules inside the lib & provide dependencies both in root level package.json as well as inside the lib but do npm i only in the root.

Also ended up here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM