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

Issue with Route middleware : vue-query hooks can only be used inside setup() function #72

Open
armenr opened this issue Mar 15, 2024 · 1 comment
Labels
question Further information is requested

Comments

@armenr
Copy link

armenr commented Mar 15, 2024

Environment

❯ node -v
v20.11.1

"@hebilicious/vue-query-nuxt": "^0.3.0",

Reproduction

composables/useQueryWrapper.ts

import { experimental_createPersister } from '@tanstack/query-persist-client-core'
import type { GetUserQuery } from '~/API'

export default async function useQueryWrapper() {
  const queryClient = useQueryClient()

  const { isLoading, isError, data, error } = useQuery({
    queryKey: ['getUser'],
    queryFn: async () => {
      const { data } = await useLeanGraphql({
        variables: { id: '9e98ae52-1f4b-47ad-9661-afb2c7efc653' },
        graphqlAction: getUser,
        fields: {
          name: 'getUser',
          fields: getUserSharedFields(true) as Field<GetUserQuery>['fields'],
        },
      })
      return data
      // console.log({ data })
    },
    persister: process.client ? experimental_createPersister({ storage: window.localStorage }) : undefined,
  })

  console.log({
    queryClient,
    isLoading,
    isError,
    data,
    error,
  })

  return { queryClient, isLoading, isError, data, error }
}

plugins/03.auth-redirect.ts

import { Amplify } from 'aws-amplify'
import config from '~/amplifyconfiguration.json'

const unprotectedRoutes = [
  'index',
  'signin',
  'signup',
  'recovery',
  'cause-areas',
  'demo-amplify',
  'cookie-policy',
  'privacy-policy',
  'recovery-confirm',
  'terms-of-service',
]

export default defineNuxtPlugin({
  name: 'AmplifyAuthRedirect',
  enforce: 'pre',
  setup() {
    addRouteMiddleware(
      'AmplifyAuthMiddleware',
      defineNuxtRouteMiddleware(async (to) => {
        try {
          // if we're running on the client, initialize Amplify
          if (process.client)
            Amplify.configure(config, { ssr: useRuntimeConfig().public.ssrEnabled })

          // does the user have a valid session?
          // !! deleted users still possess valid tokens for 1 hour (Cognito "feature")
          const { userId } = await useAuth().getCurrentUser()

          // if the user has a valid session, fetch their user data
          if (userId) {

            // !! testing simple getUser with Id query via vue-query
            try {
              const TESTINGTHIS = await useQueryWrapper()          // 👈 Doesn't work!
              useLogger().info('useQueryWrapper', TESTINGTHIS)
            }
            catch (e) {
              useLogger().error('useQueryWrapper error', e)
            }

            // existing pinia-based implementation
            if (useAuthStore().isLoggedIn === false) {
              // if not, fetch it from the API
              await useAuthStore().fetchCurrentUser(userId)
            }

            if (to.name === 'signin')
              return navigateTo('/feed')
          }
        }
        catch (e) {
          if (e instanceof Error && 'code' in e) {
            if (e.code === 'NotAuthorizedException') {
              useLogger().error('NotAuthorizedException')
              return
            }
          }

          if (!unprotectedRoutes.includes(to.name))
            return navigateTo('/signin')
        }
      }),
      { global: true },
    )
  },
})

Describe the bug

Hi! Thanks for all your great work on this plugin :)

I'm struggling with just one specific implementation.

  • I'm able to call useQueryWrapper in the setup block of one of my pages.
  • I'm able to call useQueryWrapper in my Pinia store (I <3 Pinia, but I'm tryna replace it with vue-query, so I'm really only calling useQueryWrapper from inside pinia as a test...)

In my my authStore.ts (pinia), I can successfully do this:

  useQueryWrapper().then((data) => {
    console.log("Hai antfu, posva, and herbilicious! ", data)
  })
  • I'm unable to call useQueryWrapper from inside the global middleware I create in the plugin I've shared above.

If I could, I'd implement that whole plugin differently, but this is the specific way that the AWS Amplify documentation insists that we implement a routeGuard with SSR + Nuxt3 + Amplify.

I did do lots of digging and searching, and I found this: TanStack/query#5533

I don't understand how we're not getting any context from inside a plugin...I'm just confused (and probably a bit of a newb).

Based on that discussion, I even tried to do useNuxtApp().runWithContext(async () => await useQueryWrapper()) from inside the 03.auth-redirect.ts plugin.

I'm totally stuck. Would you happen to have any suggestion or idea as to how I can get this working. I'm sure that I'm missing something stupid/ovious, but it's 4AM here and I'm already starting to lose it 😂

Thank you for any help or direction you may be able to provide! 🙌🏼

Additional context

No response

Logs

03.auth-redirect.ts:45 [ERROR] 24:03.34 DEV - useQueryWrapper error Error: vue-query hooks can only be used inside setup() function or functions that support injection context.
    at useQueryClient (useQueryClient.ts:9:11)
    at useQueryWrapper (useQueryWrapper.ts:5:23)
    at wrappred (function-metrics-helpers.mjs:42:17)
    at 03.auth-redirect.ts:41:62
    at executeAsync (index.mjs:111:19)
    at 03.auth-redirect.ts:41:51
    at async router.js:138:39
@Hebilicious
Copy link
Owner

@armenr Sorry I'm just seeing this ...
https://nuxt.com/docs/guide/concepts/auto-imports#vue-and-nuxt-composables
If you look there you'll find more info about using async and composables. You might have to do some hacks or to use

export default defineNuxtConfig({
  experimental: {
    asyncContext: true
  }
})

to do this, if your underlying platform supports it.

Let me know if you have a solution !

@Hebilicious Hebilicious added the question Further information is requested label Dec 9, 2024
@Hebilicious Hebilicious changed the title Unable to use in composable Issue with Route middleware : vue-query hooks can only be used inside setup() function Dec 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants