Getting "inject() must be called from an injection context" after upgrading to Angular 11
Asked Answered
M

2

9

After upgrading to Angular 11, I am not able to ng serve my web application anymore.

I am generating the client using Spring Doc and the latest OpenAPI generator gradle-plutin (5.0.0).

The problem appears to be related to my (generated) REST-client. Opening https://localhost:4200 will write the following into the console:

main.ts:12 Error: inject() must be called from an injection context
    at injectInjectorOnly (core.js:4901) [angular]
    at Module.ɵɵinject (core.js:4911) [angular]
    at Object.ApiModule_Factory [as factory] (meditation-rest-client.js:2885) [angular]
    at R3Injector.hydrate (core.js:11158) [angular]
    at R3Injector.get (core.js:10979) [angular]
    at :4200/vendor.js:82591:55 [angular]
    at Set.forEach (<anonymous>) [angular]
    at R3Injector._resolveInjectorDefTypes (core.js:11016) [angular]
    at new NgModuleRef$1 (core.js:25046) [angular]
    at NgModuleFactory$1.create (core.js:25100) [angular]
    at :4200/vendor.js:100468:45 [angular]
    at Object.onInvoke (core.js:28301) [angular]

The following is my tsconfig.json file:

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "module": "es2020",
    "lib": [
      "es2018",
      "dom"
    ]
  }
}

This is how I define the dependency in package.json

    "chart.js": "^2.9.4",
    "core-js": "^3.8.2",
    "meditation-rest-client": "./generated/meditation-rest-client",
    "http-server": "^0.12.3",
    "http-status-codes": "^2.1.4",
    "moment": "^2.29.1",

And this here are those generated lines which are reffered to in the error message above:

// ...

ApiModule.ɵmod = ɵngcc0.ɵɵdefineNgModule({ type: ApiModule });
ApiModule.ɵinj = ɵngcc0.ɵɵdefineInjector({ factory: function ApiModule_Factory(t) { return new (t || ApiModule)(ɵngcc0.ɵɵinject(ApiModule, 12), ɵngcc0.ɵɵinject(ɵngcc1.HttpClient, 8)); }, providers: [], imports: [[]] });
ApiModule.ctorParameters = () => [
    { type: ApiModule, decorators: [{ type: Optional }, { type: SkipSelf }] },
    { type: HttpClient, decorators: [{ type: Optional }] }
];

// ...

This used to work in Angular 9 but it won't under Angular 11.

Any idea how to fix this? I already tried setting "preserveSymlinks": true as suggested here and here.

Please let me know if you need more information.

Maricruzmaridel answered 13/1, 2021 at 21:19 Comment(0)
B
7

The issue could arise due to the generated npm package builds into some output folder /generated/meditation-rest-client. When being referenced by the frontend application, the api package resolves the import @angular/core to /generated/meditation-rest-client/node_modules/@angular/core, differing from the /node_modules/@angular/core in the project root.

The resolution would be to delete the /generated/meditation-rest-client/node_modules folder and the node_modules folder in the parents, except for the <project-root>/node_modules. Alternatively, the generated code /generated/meditation-rest-client should be copied to some location where no parent folder contains an node_modules folder.

See https://github.com/OpenAPITools/openapi-generator/issues/8447

Barrios answered 15/1, 2021 at 15:32 Comment(1)
This was precisely my case. Other team's package had @angular/core and other angular packages set as production dependencies instead of devDependencies which should be used only for building their library. Will have to connect with them and get this fixed. Thanks a lot, sir.Volute
H
17

If this is a multi project setup (aka monorepo), you have to take care of the following:

  • The root (the folder which has the projects subdir) should have a package.json and a node_modules directory
  • Only projects of type library have a package.json and they should have only peer dependencies. DON'T run npm install here! There MUST NOT be a node_modules directory here
  • application projects don't have a package.json at all and as such don't have a node_modules either
  • The library doesn't need to be listed as a dependency. Use paths in tsconfig.json's compilerOptions to use it.

I found this example skeleton project at github helpful to fix my injection problem:

https://github.com/PeterKassenaar/ng-monorepo

Hangchow answered 9/8, 2021 at 20:50 Comment(4)
I had this problem, and with your advice, I resolved it. ThanksCaesarean
Thanks, this fixed my issues too, I'm working on a monorepo with publishable UI-packages. Upgraded from Angular 9 to 13.Skulduggery
Thank you, must of had cd into the library by accident and did npm install. Spent whole day figuring out what's wrong and was about to delete my library and redo.Mitran
Thank you! my problem was that I had node_modules directory in library. As you stated, node_modules should only be in the root directory of projectBourne
B
7

The issue could arise due to the generated npm package builds into some output folder /generated/meditation-rest-client. When being referenced by the frontend application, the api package resolves the import @angular/core to /generated/meditation-rest-client/node_modules/@angular/core, differing from the /node_modules/@angular/core in the project root.

The resolution would be to delete the /generated/meditation-rest-client/node_modules folder and the node_modules folder in the parents, except for the <project-root>/node_modules. Alternatively, the generated code /generated/meditation-rest-client should be copied to some location where no parent folder contains an node_modules folder.

See https://github.com/OpenAPITools/openapi-generator/issues/8447

Barrios answered 15/1, 2021 at 15:32 Comment(1)
This was precisely my case. Other team's package had @angular/core and other angular packages set as production dependencies instead of devDependencies which should be used only for building their library. Will have to connect with them and get this fixed. Thanks a lot, sir.Volute

© 2022 - 2024 — McMap. All rights reserved.