-
-
Notifications
You must be signed in to change notification settings - Fork 522
Description
Describe the bug
useApolloClient checks wrong conditions before calling inject(). As a result, inject() can be called outside of proper context.
To Reproduce
Steps to reproduce the behavior:
- clone https://github.com/DawidKopys/nuxt-middleware-apollo-pinia-inject-bug
npm installnpm run dev- visit http://localhost:3000/
- check browser console, you should see somethign like below containing vue warnings (coming from
inject()):
provideFoo plugin
1.injectFoo middleware - regular
injected foo : foo
2.injectFoo middleware - app.runWithContext() -> inject()
[Vue warn]: inject() can only be used inside setup() or functional components.
injected foo : undefined
3.injectFoo middleware - useCounterStore() -> useQuery()
[Vue warn]: inject() can only be used inside setup() or functional components.
[Vue warn]: inject() can only be used inside setup() or functional components.
Expected behavior
"3.injectFoo middleware" doesn't produce any warnings coming from vue's inject.
Versions
vue: [email protected]
vue-apollo: ???
@apollo/client: @apollo/[email protected]
@vue/apollo-composable: @vue/[email protected]
Additional context
Currently, useApolloClient() performs wrong checks before calling inject(). It checks for presence of currentInstance (with getCurrentInstance()) and activeEffectScope (with getCurrentScope()). We shouldn't check for activeEffectScope here, otherwise useApolloClient may call inject without correct context.
Instead, it should check for currentInstance, currentRenderingInstance. currentApp with help of vue utility function created just for this purpose - hasInjectionContext(). As a result, functions such as useQuery will continiue working in navigation guards and pinia stores but we will handle case in which there is an activeEffectScope but we are out of correct context for inject().
One such edge case is calling useQuery, inside route middleware, after accessing Pinia store with useXXXStore. That is because Pinia's useStore calls app.runWithContext(fn) (here) which sets currentApp = null -> as a result, we are no longer in right context for inject.
useApolloClient fails to recognize it and we get the warnings as a result.
"2.injectFoo middleware" provides a simplified example of what is happening in above edge case.
For additional context, here is a simplified example - without nuxt, pinia or vue-apollo - of what is happenning here https://github.com/DawidKopys/vue-router-inject-warn.
I will try to create appropriate PR with a fix myself.
Also, it might be interesting to know that before Nuxt 3.8.0 it was working as expected. I believe it is due to this change. As a result of this change activeEffectScope is now set in route middleware contexts, and in consequence, the condition in useApolloClient is truthy.