Search code examples
javascriptnuxt.jssupabasepinia

Http GET request via Pinia action only works on second attempt in Nuxt app


I'm using Pinia in a Nuxt 3 application and am trying to make a GET request via useFetch when the user logs in. The request uses Nuxt's server and makes a call to a SupaBase hosted DB so I can get the username, these live in a user table that is separate from Supabase's auth table. I then store the result in Pinia global state.

For some reason, the request only works the second time I make the request, ie. after I click on a second page following login, and I cannot make it work the first time.

The action function - shown below - that makes the request to the Nuxt API sits in a Pinia AuthStore.js file and is called via a NavBar component. This means that on each page in my Nuxt app, the function will be called if the username is not saved in state.

When I test this call via Postman, it works the first time around, ie. the correct result is returned, so it seems that the request is set up correctly. I suspect the issue may have something to do with Nuxt's cache but cannot figure out why it only works the second time around in the app.

Here's the relevant code in AuthStore.js - when I run this code on my local server, I get "No data" logged on the 1st request and the correct data on the 2nd:

export const useAuthStore = defineStore('AuthStore', {
   state: () => {
      return {
         loggedIn: null,
         user: null,
         username: null,
      }
   },
   actions: {
      async loadUserName() {
         if (this.loggedIn) {
            const { data, error } = await useFetch(
               '/api/user/get-user',
               {
                  params: {
                     userId: this.user.id,
                  },
               }
            )
            if (error) {
               console.log('E:', error)
            }
            if (data.value) {
               this.username = data.value.user_name
            } else {
               console.log('No data')
            }
         }
      },
   },
})

EDIT: I need this to work on the first request as I want to show the user a button to register a username when they login.


Solution

  • Despite using async/await, the data is not available via await, this is related to the SSR nature of the response - see useFetch() response value not accessible

    The only way to access the response data is via an interceptor - this is done via a callback that doesn't have access to the Pinia state via this so I needed to call in the store to access/set it.

    Ended up looking like this:

    await useFetch('/api/user/get-user', {
       params: {
          userId: this.user.id,
       },
       onResponse({ response }) {
          const AuthStore = useAuthStore()
    
          if (response._data) {
             AuthStore.username =
                response._data.user_name
          } else {
             console.log('No data')
          }
       },
       onResponseError({ request, response }) {
          // log error here
       },
    })