注入()必须从注入上下文调用

我试图导出我的角度应用程序作为一个 npm 模块,供其他应用程序使用,但遇到了一些困难。我在互联网上其他任何地方都找不到这个错误,我已经束手无策了。

我遵循了这个教程: https://medium.com/@nikolasleblanc/building-an-angular-4-component-library-with-the-angular-cli-and-ng-packagr-53b2ade0701e

我使用 ng-packagr 将我的应用程序导出为 npm 模块。我可以成功地从一个本地文件夹安装一个简单的测试应用程序,但不能让它显示我的应用程序。

错误:

    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 (导出模块)

    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
]
}
}
}

Module.ts (使用我的模块的简单测试应用程序)

    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 { }

如果有任何帮助或建议,我都会很感激的,谢谢。

61221 次浏览

I had the same error.

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

Hope that helps!

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, e.g.

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 {}

There seems to be an issue when using npm link when consuming the library.

Solution: use projects.$name.architect.build.options.preserveSymlinks: true in the angular.json file of the client project, not the library.

Further information: https://github.com/angular/angular/issues/25813

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.

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.

If the error appears on Karma with tests, just delete de node_modules folder and install again.

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 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();

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 found that I was importing Inject from @angular/core instead of @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.

It was confusing that 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.

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.

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

Background: this is my own Angular 9 app as I was trying to locally import my own Angular 9 library

My issue was this flag in the tsconfig.json of my own library which I had built locally:

  "angularCompilerOptions": {
"strictInjectionParameters": true
}

According to the Angular documentation:

When true, reports an error for a supplied parameter whose injection type cannot be determined. When false, constructor parameters of classes marked with @Injectable whose type cannot be resolved produce a warning. The recommended value is true, but the default value is false.

https://angular.io/guide/angular-compiler-options#strictinjectionparameters

To be honest, I don't know much about that flag beyond that description and can go without it; it was generated in a new project anyways.