Difference between Asyncdata vs Fetch

vue.jsVuejs2Vuexnuxt.js

vue.js Problem Overview


What is the exact difference between fetch and async data. The official documentation says the following:

> asyncData > > You may want to fetch data and render it on the server-side. Nuxt.js > adds an asyncData method that lets you handle async operations before > setting the component data. > > asyncData is called every time before loading the component (only for > page components). It can be called from the server-side or before > navigating to the corresponding route. This method receives the > context object as the first argument, you can use it to fetch some > data and return the component data.


> Fetch > > The fetch method is used to fill the store before rendering the page, it's > like the asyncData method except it doesn't set the component data. > The fetch method, if set, is called every time before loading the > component (only for page components). It can be called from the > server-side or before navigating to the corresponding route. > > The fetch method receives the context object as the first argument, we > can use it to fetch some data and fill the store. To make the fetch > method asynchronous, return a Promise, nuxt.js will wait for the > promise to be resolved before rendering the component.


Fetch is been used to fill the store with data? But in asyncData is this also possible to commit trough a store? I don't understand why there are two methods for.

Both methods are running server-side on the initial load, after that when you navigate through the applicatie it runs client side.

Can someone explain me the advantage of use these methods above the other?

Thanks for help.

vue.js Solutions


Solution 1 - vue.js

Let me re-iterate few points as a pretext to what i'm going to say

  • asyncData can set component level objects and access vuex store
  • fetch cannot set component level objects but has access to vuex store
  • Both asyncData & fetch will be triggered in server side during initial load
  • After initial load, asyncData and fetch will be triggered when the corresponding page routes are invoked

1) if your design is

  • Use vuex store as a central repository
  • Access data from the vuex store for the entire application

then use fetch

2) if your design is

  • Use vuex store as a central repository
  • Have options to set component level objects
  • Data fetched in a particular route is used only by a single component
  • Need flexibility to have permission to either vuex store or set component level object

then use asyncData

> Can someone explain me the advantage of use these methods above the > other?

i don't see any drawbacks in using asyncData or fetch

Choosing asyncData or fetch totally depends on your architecture

Update for NuxtJS >= 2.12

Several points mentioned in the answer no longer apply when using newer NuxtJS versions (>= 2.12). Official RFC announcement here.

A good explanation of the new behaviour and differences between asyncData and the new fetch can be found in this post in the NuxtJS official blog.

As for choosing between both, I believe the original answer still applies:

> i don't see any drawbacks in using asyncData or fetch

> Choosing asyncData or fetch totally depends on your architecture

Solution 2 - vue.js

TL;DR - use asyncData for stuff which must be loaded before rendering a page, use fetch for everything else.

Key differences:

Availability
  • asyncData is only available on page components
  • fetch can be used on any component (including page components)
Loading
  • asyncData blocks the page transition until it resolves. This means the data properties returned are guaranteed to be available on the component. But it also means users may have to wait longer before seeing content.
  • fetch exposes a $fetchState.pending property and it's up to you how to handle that
Error handling
  • if an error is thrown in asyncData the page is not rendered
  • fetch exposes a $fetchState.error property and it's up to you how to handle that

Solution 3 - vue.js

One point I'd like to make that I don't see mentioned above (at least, not clearly). asyncData automatically MERGES the data into your page's data() object. Fetch does not. With fetch, it's up to you to do with the data as you please.

Solution 4 - vue.js

The 1st

Because of the different nature of asyncData and fetch there is one important advantage in case of asyncData - Nuxt waits for the asyncData hook to be finished before navigating to the next page.

Taking from here: > Unlike fetch, the promise returned by the asyncData hook is resolved during route transition. This means that no "loading placeholder" is visible during client-side transitions (although the loading bar can be used to indicate a loading state to the user). Nuxt will instead wait for the asyncData hook to be finished before navigating to the next page or display the error page).

What does it mean on practise?

Lets imagine you have the next structure of layout:

  • Header
  • Content
  • Footer

In case of using fetch when you open a new page, you may see for few seconds just Header and Footer (because data for Content is downloading). In case of using asyncData you avoid this problem and see a new page with Header + Content + Footer (however the disadvantage of this method is that you need to wait the same few seconds to download Content data).

The 2nd

I see in different places in web that when you want to store something in vuex, you need to use fetch - this is incorrect.

In the code below (taken from my project) you can find implementation of asyncData and fetch that both store data into vuex.

<script>
import { mapActions, mapMutations, mapState } from 'vuex'

export default {
  name: 'PagesBlog',

  async asyncData ({ store }) {
    if (!store.state.global.blogAuthors.length) {
      store.commit('global/blogAuthorsSet', await blogAuthorsDownload())
    }

    await store.dispatch('global/blogsDownloadAndSet')
  },

  async fetch () {
    if (!this.blogAuthors.length) {
      this.blogAuthorsSet(await blogAuthorsDownload())
    }

    await this.blogsDownloadAndSet()
  },

  computed: {
    ...mapState('global', [
      'blogAuthors'
    ])
  },

  methods: {
    ...mapActions('global', [
      'blogsDownloadAndSet'
    ]),

    ...mapMutations('global', [
      'blogAuthorsSet'
    ])
  }
</script>

Summary

  1. If you have some important data (either visible to user or not visible to user, but needed for some hidden calculation) - use asyncData.

  2. If you want to see page with all information (for example when you have Header + Content + Footer) - use asyncData.

  3. If you have some data that can be loaded a bit later - use fetch.


Fetch Hook and Nuxt Lifecycle

Solution 5 - vue.js

I. fetch and asyncData are processed on the server-side.

II. can see the difference in the way to use them:

a) fetch: change store data

<script>
export default {
  async fetch ({ store, params }) {
    await store.dispatch('GET_STARS');
  }
}
</script>

b) asyncData: change context (component data)

<script>
export default {
  asyncData (context) {
    return { project: 'nuxt' }
  }
}
</script>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYakalentView Question on Stackoverflow
Solution 1 - vue.jsdivineView Answer on Stackoverflow
Solution 2 - vue.jsTamlynView Answer on Stackoverflow
Solution 3 - vue.jskp123View Answer on Stackoverflow
Solution 4 - vue.jsTitanFighterView Answer on Stackoverflow
Solution 5 - vue.jsHoangYellView Answer on Stackoverflow