Nuxt.js: validate after fetch

Created on 2 Nov 2017  路  8Comments  路  Source: nuxt/nuxt.js

Looking at Nuxt's request/navigation schema (and after some debugging) I discovered that a Page component's asyncData and fetch methods are called _after_ the validate method.

Would it be possible to flip this order so that validate is called _after_ asyncData and fetch?

Here is my use case:

  1. All of my app's data is stored in the Vuex store
  2. When navigating to posts/_id, I use the route param id to fetch some data from an API
  3. I do so using the posts/_id.vue page component's fetch method, passing along the route param id 鈥攕omething like: store.dispatch('fetchPost', route.params.id)
  4. An async fetchPost action in the Vuex store calls my API with the payload id, returns a post record and then that record is committed to the store into a posts collection/array
  5. Assuming that the call to the API was successful and a post exists for the provided id, I will now have my post record in my Vuex store.state.posts collection
  6. I would then like to be able to validate my dynamic Post page by finding my post record in the store's posts collection (again using the route.params.id)
  7. However since validate is called _before_ fetch, my store's posts collection will be empty so that lookup returns no record and the validation fails

The only way around this is to use the nuxtServerInit action which does get called _before_ a page's validate method. However, this then means that this action will get quite cumbersome as I move or duplicate my route specific async calls to my API to within this action.

If validate were called after fetch then this wouldn't be necessary and the nuxtServerInit action could remain relatively pure and simple.

Perhaps there is a reason why validate is called before that I am not aware of鈥攅ither way, I would appreciate any help/suggestions.

BTW Nuxt is literally the best thing since sliced bread. Fantastic work 馃帀

This question is available on Nuxt.js community (#c1786)
help-wanted question

Most helpful comment

@moritzsternemann this is essentially what I ended up doing鈥攖hough there is a much more elegant way of throwing an error in Nuxt.

Nuxt provides the error function you are referencing in your snippet above on the context object that is passed to both the asyncData and fetch methods.

Here's an example:

export default {
  async fetch({ store, error }) {
    if (store.getters.isAuthenticated) {
      await store.dispatch('fetchProfile')
    } else {
      error({ statusCode: 401, message: 'Unauthorised' })
    }
  }
}

All 8 comments

Hi @wagerfield

Actually, validate is used only to validate query parameters schema (query & params) to avoid calling asyncData & fetch with incorrect data.

You can add a condition after your fetch method to check if the post exists, and if not show an error page directly :)

Makes total sense, thanks a lot @Atinux!

With this being the case, what is the best way to throw and render an error should my async fetch action return an error?

After some digging I found out that the validation handler calls the following nuxt error handler if validate() returns false:

vm.$root.$nuxt.error({ statusCode: 404, message: 'Some error message' })

Could we get quick comment from @Atinux if this is the preferred way to show the error page from within a page component?

Hi @moritzsternemann

You can use the error property from context in asyncData or fetch directly to show the error page :)

Perfect, thanks!

@moritzsternemann this is essentially what I ended up doing鈥攖hough there is a much more elegant way of throwing an error in Nuxt.

Nuxt provides the error function you are referencing in your snippet above on the context object that is passed to both the asyncData and fetch methods.

Here's an example:

export default {
  async fetch({ store, error }) {
    if (store.getters.isAuthenticated) {
      await store.dispatch('fetchProfile')
    } else {
      error({ statusCode: 401, message: 'Unauthorised' })
    }
  }
}

Haha @Atinux you beat me to it!

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nassimbenkirane picture nassimbenkirane  路  3Comments

vadimsg picture vadimsg  路  3Comments

mikekidder picture mikekidder  路  3Comments

jaredreich picture jaredreich  路  3Comments

surmon-china picture surmon-china  路  3Comments