inject() must be called from an injection context after upgrading Angular from v14 to v17

Discussão em 'Angular' iniciado por IMeyers20, Dezembro 28, 2024.

  1. IMeyers20

    IMeyers20 Guest

    I've recently updated my Angular project from v14 to v17. After doing so, I have received many injection errors when running my project / test code.

    I am using Angular 17.3.2, Node 20.11.1, Typescript 5.4.3 and NX 18.2.3.

    I am aware that as of v16, I should be using runInInjectionContext, but I feel as if I'm not understanding where all it should be used from the documentation. Do I have to add that everywhere that a service is used? And does it need to be added in services AND components?

    The exact error stack when running my project:

    main.ts:14 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 `runInInjectionContext`. Find more at https://angular.io/errors/NG0203
    at injectInjectorOnly (core.mjs:1093:15)
    at Module.ɵɵinject (core.mjs:1106:60)
    at Object.RouterModule_Factory [as useFactory] (router.mjs:424:103)
    at Object.factory (core.mjs:3322:38)
    at core.mjs:3219:47
    at runInInjectorProfilerContext (core.mjs:866:9)
    at R3Injector.hydrate (core.mjs:3218:21)
    at R3Injector.get (core.mjs:3082:33)
    at injectInjectorOnly (core.mjs:1100:40)
    at ɵɵinject (core.mjs:1106:60)


    The exact function that is throwing the error in core.mjs:1093:

    function injectInjectorOnly(token, flags = InjectFlags.Default) {
    if (_currentInjector === undefined) {
    throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode &&
    `inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with \`runInInjectionContext\`.`);
    }
    else if (_currentInjector === null) {
    return injectRootLimpMode(token, undefined, flags);
    }
    else {
    const value = _currentInjector.get(token, flags & InjectFlags.Optional ? null : undefined, flags);
    ngDevMode && emitInjectEvent(token, value, flags);
    return value;
    }
    }


    Error happens in my main.ts at platformBrowserDynamic().bootstrapModule(AppModule):

    platformBrowserDynamic()
    .bootstrapModule(AppModule)
    .then(platformRef => {
    let injector = platformRef.injector;
    runInInjectionContext(injector, () => {
    let notificationService = inject(NotificationService);
    let authService = inject(AuthService);
    let coBrandingService = inject(CoBrandingService);
    let coreCacheService = inject(CoreCacheService);
    let eventService = inject(EventService);
    let loginService = inject(LoginService);
    authService.RegisterHook(notificationService);
    authService.RegisterHook(coBrandingService);
    authService.RegisterHook(coreCacheService);
    authService.RegisterHook(eventService);
    authService.RegisterHook(loginService);
    });
    });


    Component usage I have tried, but not yet commited to adding everywhere:

    export class MyComponent{
    constructor(private service1: FirstService, private service2: SecondService, private injector: EnvironmentInjector) {}

    ngOnInit() {
    runInInjectionContext(this.injector, () => {
    inject(FirstService);
    inject(SecondService);
    })
    }
    }


    Service usage I have tried, but not yet commited to adding everywhere:

    @Injectable()
    export class MyService{
    constructor(private service2: SecondService, private injector: EnvironmentInjector) {}

    ServiceMethod() {
    runInInjectionContext(this.injector, () => {
    let result = this.service2.SecondServiceMethod();
    return result;
    })
    }
    }


    I have also tried adding @angular/* to compilerOptions.paths as shown here

    And I have tried setting build.options.preserveSymlinks to true as discussed here

    I have ensured that the module I am attempting to bootstrap is providing the services that should be available in the InjectionEnvironment:

    @NgModule({
    declarations: [
    AppComponent
    ],
    providers: [
    NotificationService,
    AuthService,
    CoBrandingService,
    CoreCacheService,
    EventService,
    LoginService,
    { provide: APP_BASE_HREF, useValue: '/' }
    // ... Others removed for brevity ...
    ],
    bootstrap: [
    AppComponent
    ]
    })
    export class AppModule { }

    Continue reading...

Compartilhe esta Página