How to implement asynchronous middleware in Nuxt.js

16,306

From the Nuxt documentation: "A middleware can be asynchronous. To do this, simply return a Promise or use the 2nd callback argument"

Therefore, something like this should work, since axios returns a promise:

import axios from 'axios'

export default function ({ store }) {
  return axios.get('http://example.com/getsession')
    .then(response => {
      store.commit('setSession', response)
    })
    .catch(() => {
      store.commit('clearSession')
    })
}
Share:
16,306

Related videos on Youtube

Wouter Florijn
Author by

Wouter Florijn

Co-founder & CTO, Dyme.

Updated on September 15, 2022

Comments

  • Wouter Florijn
    Wouter Florijn over 1 year

    I have a Nuxt middleware file that fetches the session from an external api. This session is used to set things such as locale, so it's important that it is fetched before any page loads. Currently it looks like this:

    middleware/session.js

    import axios from 'axios'
    
    export default function ({ store }) {
      axios.get('http://example.com/getsession')
        .then(response => {
          store.commit('setSession', response)
        })
        .catch(() => {
          store.commit('clearSession')
        })
    }
    

    store/index.js

    export const state = () => ({
      session: {}
    })
    
    export const mutations = {
      setSession (state, session) {
        state.session = session || {}
      },
      clearSession (state) {
        state.session = {}
      }
    }
    
    export const getters = {
      session (state) {
        return state.session || {}
      }
    }
    

    The session is fetched using Axios and stored in a Vuex store. However, since it is asynchronous, this data isn't available instantly, and plugins or other middleware that try to get the session from the store simply get an empty object (which is the default).

    Examples where this breaks things:

    • Another middleware used for certain routes checks if the user is logged in based on the session.user. The session is still empty and therefore session.user is undefined at this point.
    • I'm using the vue-i18n plugin to translate pages. It gets its initial locale from the session in the store. But since this session is empty at the moment it is retrieved, i18n always uses the fallback locale.

    Is there a way to await the response of the api call before proceeding? Or is there maybe a different/better way to perform this api call?

    • Aldarund
      Aldarund over 6 years
      How did u solve this?
  • Fasco
    Fasco almost 5 years
    But is it possible to return a promise from a store in the middleware? Because here, you call directly in the middleware.
  • Augusto Destrero
    Augusto Destrero over 2 years
    @Fasco yes. Supposing that you have an action getSession in your Vuex store, you can return in your middleware function the value returned by the store dispatch method, because that's also a Promise. E.g. return store.dispatch('getSession')