5

I created a simple angular standalone component that uses an injection token for configuration:

export const PERSON_DEFAULT_OPTIONS = new InjectionToken<IPersonDefaults>('...')

export interface IPersonDefaults { ... }

export const providePersonDefaultOptions = (options: IPersonDefaults): Provider => ({
    provide: PERSON_DEFAULT_OPTIONS,
    useValue: options
})

@Component({...})
export class StandaloneComponent {
   readonly #config = inject(PERSON_DEFAULT_OPTIONS, {optional: true})
}

In my main.ts I then just call providePersonDefaultOptions() with my values and everything works great.

Now I've taken that token/interface/component and put it into an npm library. When I try and run the app again, it gives me the following error:

Error: NG0203: inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with EnvironmentInjector#runInContext

I'm not understanding why that code doesn't work as an npm library, since it's still a field initializer where it's being set.

Raphaël Balet
  • 6,334
  • 6
  • 41
  • 78
Gargoyle
  • 9,590
  • 16
  • 80
  • 145

1 Answers1

1

This error may happen because of

1: 2 @angular/core ending up in the bundled application

The cause is that the two separate workspaces both have their own @angular/core packages, and both end up in the bundled application. The Angular runtime keeps its state in top-level module variables that are private to that module, but having two occurrences of that module (from both instances of @angular/core) you run into situations where state is only initialized correctly in one instance, not the other. In this case the injection context is only available in the "primary" runtime, but the parts of the app that were bundled from the "secondary" library parts will depend on the "secondary" runtime state. - JoostK

My problem

I had 3 libraries a, b and c.
a and b where both importing c, but a used a different version than b. one were under angular 14, the other on angular 16.

Which made it use 2 different @angular/core

Solution

I've updated every version of my library to use exactly the same version.

2: Old es target

If you're migrating to angular v16, you may need to change the target to ES2022

// tsconfig.json

"compilerOptions": {
  "lib": ["ES2022", "dom"],
  "module": "ES2022",
  "target": "ES2022",
}
Raphaël Balet
  • 6,334
  • 6
  • 41
  • 78