web-dev-qa-db-ja.com

Nuxt.jsで非同期ミドルウェアを実装する方法

外部APIからセッションをフェッチするNuxtミドルウェアファイルがあります。このセッションはロケールなどを設定するために使用されるため、ページが読み込まれる前にフェッチすることが重要です。現在、次のようになっています。

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 || {}
  }
}

セッションはAxiosを使用してフェッチされ、Vuexストアに保存されます。ただし、非同期であるため、このデータはすぐには利用できず、ストアからセッションを取得しようとするプラグインまたはその他のミドルウェアは、単に空のオブジェクト(デフォルト)を取得します。

これが物事を壊す例:

  • 特定のルートに使用される別のミドルウェアは、ユーザーがsession.userに基づいてログインしているかどうかをチェックします。セッションはまだ空であるため、この時点でsession.userundefinedです。
  • 私はvue-i18nプラグインを使用してページを翻訳しています。ストア内のセッションから初期ロケールを取得します。ただし、このセッションは取得された時点では空であるため、i18nは常にフォールバックロケールを使用します。

続行する前にAPI呼び出しの応答を待つ方法はありますか?それとも、このapi呼び出しを実行するための別の/より良い方法がありますか?

6
Wouter Florijn

Nuxtのドキュメントから: "ミドルウェアは非同期にすることができます。これを行うには、Promiseを返すか、2番目のコールバック引数を使用します"

したがって、axiosは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')
    })
}
2
Laura