angular: @Inject(token) throws 'No provider for @Inject(Token initState)!'

@vsavkin has a great article on state management, so I use it in my app. Victor provides a Plunkr to the article and it works but it uses beta.1.

Now, I created a new project with angular-cli (the latest) and added state management to it, splitting it to separate files. See this project - project done in VS Code. But when I run it I get the following error:

No provider for @Inject(Token initState)!

but there IS injection (file /shared/state/diconfig.ts):

// -- DI config
export const initState = new OpaqueToken("initState");
export const dispatcher = new OpaqueToken("dispatcher");
export const state = new OpaqueToken("state");

export const stateAndDispatcher = [
  provide(initState, {useValue: {todos: [], visibilityFilter: 'SHOW_ALL'}}),
  provide(dispatcher, {useValue: new Subject<Action>(null)}),
  provide(state, {useFactory: stateFn, deps: [new Inject(initState), new Inject(dispatcher)]})
];

So, why it worked in beta.1 and doesn’t work in RC1? Is this a bug or just something changed in the DI?

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 1
  • Comments: 15 (5 by maintainers)

Most upvoted comments

Thank you! Hopefully this thread will help others too.

@alvipeo you are right, in that in the past we were more free and would auto unwrap the Inject, but that was not correct. The correct behavior is the current behavior.

Here is how to think about it.

const token = new OpequeToken('token');
class MyClass {
  constructor(@Inject(token) x:any){}
}

Here the @inject is needed because we need a decorator to store the token someplace.

In this case we don’t need it:

provide(MyClass, {useFactory: ..., deps: [token]}

Because if we wrap it we are saying that the what we are injecting is the Inject instance rather than the token. So that was incorrect behavior in the past.

If we write this:

provide(MyClass, {useFactory: ..., deps: [token]}

it would mean:

const token = new OpequeToken('token');
class MyClass {
  constructor(@Inject(new Inject(token)) x:any){}
}

which is not what you mean.