Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to use inject() for element injector hierarchy #47566

Closed
JeanMeche opened this issue Sep 28, 2022 · 12 comments
Closed

Add ability to use inject() for element injector hierarchy #47566

JeanMeche opened this issue Sep 28, 2022 · 12 comments
Labels
area: core Issues related to the framework runtime core: di feature: insufficient votes Label to add when the not a sufficient number of votes or comments from unique authors feature Issue that requests a new feature
Milestone

Comments

@JeanMeche
Copy link
Member

JeanMeche commented Sep 28, 2022

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

core

Is this a regression?

No

Description

When providing a Service in a component, inject() triggers NullInjectorError when called within runInContext :

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [Service],
})
export class AppComponent {
  public constructor(injector: EnvironmentInjector, service: Service) {
    console.log(service); // OK
    console.log(inject(Service)); //OK

    setTimeout(() => {
      injector.runInContext(() => {
        console.log(inject(Service)); //KO
      });
    }, 100);
  }
}

This does not happen

  • if the service is providedIn:'root'
  • if the service is provided in the module

Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/angular-ivy-yccqgi?file=src%2Fapp%2Fapp.component.ts,src%2Fapp%2Fapp.component.html

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

Angular 14.2.3
@pkozlowski-opensource
Copy link
Member

This works as designed: EnvironmentInjector has only providers configured on the application / NgModule level - it doesn't "see" providers configured on the component level.

Not sure what is your real-life use-case, but you could always do:

export class AppComponent {
  public constructor(private _injector: Injector, service: Service) {
    console.log(service); // OK
    console.log(inject(Service)); //OK

    setTimeout(() => {
      console.log(this._injector.get(Service)); //KO
    }, 100);
  }
}

https://stackblitz.com/edit/angular-ivy-jujagc?file=src%2Fapp%2Fapp.component.ts,src%2Fapp%2Fapp.component.html

@pkozlowski-opensource pkozlowski-opensource added area: core Issues related to the framework runtime core: di labels Sep 28, 2022
@ngbot ngbot bot added this to the needsTriage milestone Sep 28, 2022
@JeanMeche
Copy link
Member Author

JeanMeche commented Sep 28, 2022

Thx @pkozlowski-opensource, It this mentioned somewhere in the documentation ?
If not, it would be a good idea to add it.

In my use case, I have objects created outside DI, but they still need to get access to injected services.

@pkozlowski-opensource
Copy link
Member

In my use case, I have objects created outside DI, but they still need to get access to injected services.

Currently your best option is to define those services on the application level.

@pkozlowski-opensource pkozlowski-opensource added the feature Issue that requests a new feature label Sep 28, 2022
@ngbot ngbot bot modified the milestones: needsTriage, Backlog Sep 28, 2022
@pkozlowski-opensource
Copy link
Member

@alxhub I've marked this is a feature request but please let me know if you've got any additional concerns.

@angular-robot angular-robot bot added the feature: votes required Feature request which is currently still in the voting phase label Sep 29, 2022
@angular-robot
Copy link
Contributor

angular-robot bot commented Sep 29, 2022

This feature request is now candidate for our backlog! In the next phase, the community has 60 days to upvote. If the request receives more than 20 upvotes, we'll move it to our consideration list.

You can find more details about the feature request process in our documentation.

@antischematic
Copy link

antischematic commented Sep 30, 2022

It's possible to create an environment injector that inherits from the node injector, would it be possible to widen the type signature so that createEnvironmentInjector allows this without a type cast? Alternatively, could we get runInContext added to the Injector class?

@Component({
  providers: [Service]
})
class AppComponent {
  constructor(parent: Injector) {
    const injector= createEnvironmentInjector([], parent as EnvironmentInjector)
    setTimeout(() => {
      injector.runInContext(() => {
        console.log(inject(Service)); // now it works
      });
    }, 100);
  }
}

@atscott atscott changed the title NullInjectorError when using inject() in runInContext Add ability to use inject() for element injector hierarchy Oct 3, 2022
@angular-robot
Copy link
Contributor

angular-robot bot commented Nov 8, 2022

Just a heads up that we kicked off a community voting process for your feature request. There are 20 days until the voting process ends.

Find more details about Angular's feature request process in our documentation.

@Jonathan002
Copy link

Jonathan002 commented Nov 26, 2022

+1 for component injector.runInContext. I need one for each of my canvas components. I have a canvas game component that needs to run new CharacterSprite(customOptionsPerInstance). The CharacterSprite is initialized after a server gets data so it is async. Inside CharacterSprite I use inject(canvasRef) - which is provided by each canvas component instance. It definitely beats having to do new CharacterSprite(canvasRef, customOptionsPerInstance).

@angular-robot
Copy link
Contributor

angular-robot bot commented Nov 28, 2022

Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage.

We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package.

You can find more details about the feature request process in our documentation.

@angular-robot angular-robot bot added feature: insufficient votes Label to add when the not a sufficient number of votes or comments from unique authors and removed feature: votes required Feature request which is currently still in the voting phase labels Nov 28, 2022
@akhilsai1969
Copy link

Is this issue still open? If yes, Can you assign it to me?

@JeanMeche
Copy link
Member Author

Fixed by #49396, we can now use runInInjectionContext

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Feb 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: core Issues related to the framework runtime core: di feature: insufficient votes Label to add when the not a sufficient number of votes or comments from unique authors feature Issue that requests a new feature
Projects
None yet
Development

No branches or pull requests

5 participants