0

Suppose I have an app with a concept of an authenticated user, which is managed by the UserService. While the authenticated user can change throughout the course of the life of the application (e.g. login/logout), most of my components only care about who the current user is at the moment they are created, and this value will never change so long as the component exists. For these cases, I am looking for the most concise way to inject the current user.

What I'd like to do is be able to inject the user into the component without the layer of indirection of the UserService. That is, instead of:

class FooComponent {
  private user: User;

  constructor(userService: UserService) {
    this.user = userService.get();
  }
}

I'd love to do something like

class FooComponent {
  constructor(private user: User) {}
}

I tried implementing this using factory providers by including a snippet similar to the following (in app.module.ts):

{
  provide: User,
  useFactory: (userService: UserService) => userService.get(),
  deps: [UserService]
}

This worked well, but I noticed that the factory function is only invoked the first time a User is needed for injection, and the result is memoized for all future uses. The memoization would mean that any component attempting to inject the current user would always get the first value returned, meaning that you'd get the wrong answer if you logged out and then back in as a different user. Is it possible to disable that memoization?

In an angular 1 app, I did a similar thing using the resolve mechanism in the router, but this same mechanism is more verbose in angular 2, making it more verbose and complex than the approach of injecting the UserService.

  • Thanks @günter-zöchbauer for your help! I had seen that question text but it seemed like a separate issue so I did not dig in. Sorry for the unintentional duplicate, I really appreciate it. – Jim Griswold Mar 15 '17 at 15:48
  • The duplicate is no problem. If you still think your question is different, I can reopen it, but I was sure it's exactly the same. – Günter Zöchbauer Mar 15 '17 at 15:50
  • I think it is ultimately the same problem. I was hoping that there'd be a mechanism in the DI system to inject the value you ultimately want without the component having to be aware that it must invoke a function or similar to get it. Good to know, thanks again for pointing me in that direction. – Jim Griswold Mar 15 '17 at 16:06
  • I'm sure there isn't. Angular just always returns the same instance from the first matching provider it finds. – Günter Zöchbauer Mar 15 '17 at 16:07

0 Answers0