-
Notifications
You must be signed in to change notification settings - Fork 725
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
toResolvedValue throwing incorrect error: "Unexpected asyncronous service when resolving service" #1759
Comments
Hey @holotrek, As you corretclty point const expectedNinja = await container.getAsync<Combatant>(
CURRENT_COMBATANT_TYPE
);
// ...
const expectedSamurai = await container.getAsync<Combatant>(
CURRENT_COMBATANT_TYPE
); I think I should update that section to indicate this. I'm closing the issue now, but if you think there's anything else to discuss or the issue should be reopen, feel free to ping me 🙂 |
@notaphplover Hmm, ok thanks... I guess then I don't really understand the point of waiting for the promise to be resolved before injecting it into the other Essentially this is a little more code, but is much clearer as to what is actually happening: container
.bind(katanaDbCollectionSymbol)
.toResolvedValue(
(
connection: Promise<AwesomeDbDriverConnection>,
): Promise<AwesomeDbDriverCollection<Katana>> => async {
return (await connection).getCollection(Katana);
},
[dbConnectionSymbol],
)
.inSingletonScope();
const collection = container.getAsync<AwesomeDbDriverCollection<Katana>>(katanaDbCollectionSymbol); |
Hey @holotrek, you should not await for a promise since container
.bind(katanaDbCollectionSymbol)
.toResolvedValue(
(
connection: AwesomeDbDriverConnection,
): AwesomeDbDriverCollection<Katana> => async {
return connection.getCollection(Katana);
},
[dbConnectionSymbol],
)
.inSingletonScope();
const collection = await container.getAsync<AwesomeDbDriverCollection<Katana>>(katanaDbCollectionSymbol);
You are required to await the I hope it makes sense now 🙂 |
@notaphplover No, I understand how it works. My example is describing what would be more clear if you did NOT resolve the parameter passed to |
I see. Ok, then I'll try to explain the rationale behind this behavior. Long story short: this behavior is the intended one in order to provide a good developer experience while providing a consistent behavior. Why do we provide resolved value params instead of promises?Well, let's say we go your way: container
.bind(katanaDbCollectionSymbol)
.toResolvedValue(
(
connection: Promise<AwesomeDbDriverConnection>,
): Promise<AwesomeDbDriverCollection<Katana>> => async {
return (await connection).getCollection(Katana);
},
[dbConnectionSymbol],
)
.inSingletonScope(); It seems clear But the main reason is that the core engine does not only work with resolved values. A resolved value can be an async function, but a class constructor cannot. Providing promise values in a class constructor would be painful in lots of use cases since I hope I made myself clear now 🙂. |
Is there an existing issue for this?
Current behavior
Using
.toResolvedValue
to attempt to resolve a promise into the expected response results in an error "Unexpected asyncronous service when resolving service" despite the fact that it is not resolving the promise.See this code for a minimal reproducible example.
Steps to reproduce
npm i
npm run web
Expected behavior
As stated here,
.toResolvedValue
is supposed to "wait for the promise to resolve before returning the resolved value to their dependent services". The dependency passed in bound to the symbolGET_COMBATANT_CHOICE_TYPE
is the typePromise<Combatant>
, but this language implies that it should automatically resolve to the parameter of typeCombatant
for the binding toCURRENT_COMBATANT_TYPE
. Therefore no promise should remain.Possible solution
No response
Package version
7.1.0
Node.js version
18.20.4
In which operating systems have you tested?
Stack trace
No response
Other
No response
The text was updated successfully, but these errors were encountered: