Skip to content

Scoped InjectionToken #60003

@muhamedkarajic

Description

@muhamedkarajic

Which @angular/* package(s) are the source of the bug?

core

Is this a regression?

No

Description

Given:

export const MY_SERVICE = new InjectionToken<{ data: string }>('MyService', {
    factory: () => {
        console.log('called MyService factory')
        return {
            data: 'some data',
            onDestroy: () => {
                console.log('Cleaning up resources...');
            }
        };
    }
});

When:

@Component({
    template: ``,
    providers: [
        {
            provide: MY_SERVICE,
            useClass: (MY_SERVICE as any)
        } as Provider
    ],
    standalone: false
})
export class SomeComponent implements OnInit, OnDestroy {
    myService = inject(MY_SERVICE);

    ngOnInit() {
        console.log(myService);
    }

Then: ERROR.

Please provide a link to a minimal reproduction of the bug

I think I did.

Please provide the exception or error you saw

core.mjs:6846 ERROR TypeError: Cannot read properties of undefined (reading 'ngOnDestroy')
    at registerDestroyHooksIfSupported (core.mjs:32474:39)
    at resolveProvider (core.mjs:32387:17)
    at resolveProvider (core.mjs:32363:13)
    at providersResolver (core.mjs:32350:9)
    at definition.providersResolver (core.mjs:32604:20)
    at initializeDirectives (core.mjs:17488:17)
    at resolveDirectives (core.mjs:17405:9)
    at elementStartFirstCreatePass (core.mjs:17796:9)
    at ComponentFactory.create (core.mjs:17975:35)
    at ViewContainerRef.createComponent (core.mjs:18287:47)
    at RouterOutlet.activateWith (router.mjs:2905:35)
    at ActivateRoutes.activateRoutes (router.mjs:3319:40)
    at router.mjs:3272:18
    at Array.forEach (<anonymous>)
    at ActivateRoutes.activateChildRoutes (router.mjs:3271:29)
    at ActivateRoutes.activate (router.mjs:3183:14)

// In source code of angular
function registerDestroyHooksIfSupported(tView, provider, contextIndex, indexInFactory) {
    const providerIsTypeProvider = isTypeProvider(provider);
    const providerIsClassProvider = isClassProvider(provider);
    if (providerIsTypeProvider || providerIsClassProvider) {
        const classToken = providerIsClassProvider ? resolveForwardRef(provider.useClass) : provider;
        const prototype = classToken.prototype;
        const ngOnDestroy = prototype.ngOnDestroy; // HERE IT FAILS

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 19.1.7
Node: 20.18.1
Package Manager: npm 10.8.2
OS: darwin arm64

Angular: 19.1.6
... common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, router, service-worker

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1901.7
@angular-devkit/build-angular   19.1.7
@angular-devkit/core            19.1.7
@angular-devkit/schematics      19.1.7
@angular/cli                    19.1.7
@angular/material               19.1.4
@angular/pwa                    19.1.7
@schematics/angular             19.1.7
rxjs                            7.8.1
typescript                      5.6.3
zone.js                         0.15.0

Anything else?

I wonder if this is possible and if not what makes it not possible. Do I really have to make concrete classes to have this functionality?

P.S: Get the same error when its not having onDestroy.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: coreIssues related to the framework runtimecore: di

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions