56

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.

Community
  • 1
  • 1
Yakalent
  • 872
  • 1
  • 8
  • 16

4 Answers4

87

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

aj-vargas
  • 48
  • 7
divine
  • 3,800
  • 2
  • 22
  • 28
  • 2
    upvoted! can I call fetch manually, i have a universal mode nuxt app where on one page I must paginate a table fetching data from the server without changing the page, if I click next page button should I call fetch manually or how – PirateApp Dec 07 '18 at 03:38
  • 2
    @PirateApp my practical experience is, you cannot execute 'fetch' manually, behavior of 'fetch' is controlled by nuxtjs. if you need to trigger any events (for dataFetch) after pageLoad, better to write a customMethod for dataFetch and bind the 'nextPage button' to it – divine Dec 07 '18 at 14:52
  • What about not using them at all, and using created or mounted hooks instead? – Primoz Rome Apr 09 '19 at 13:49
  • 1
    @PrimozRome `created & mounted` hooks always runs on the client side. on first request to the nuxtapp for a particular route `asyncData & fetch` will run on the server side. So with `asyncData & fetch`, you have the opportunity to load the data into client without any ajax request after page load in client side as you would do for `created & mounted` hooks – divine Apr 09 '19 at 15:19
  • @divine yes that is correct, thanks for explanation. I forgot to mention in my comment if using Nuxt.js app in SPA mode only. Then it should be the same using `fetch()` or `created()` hook, correct? – Primoz Rome Apr 10 '19 at 13:27
  • @PrimozRome yes correct, in spa whatever goes into `asyncData` or `fetch` will be invoked first then `created` hook gets invoked then `mounted` hook gets invoked. So `asyncData` or `fetch` gets invoked before the component gets `created`. – divine Apr 10 '19 at 14:04
  • I want to fill the VUEX store with data in the fetch method. Is this data then available in the asyncData method? I cannot understand which one runs first... – Tom Franssen Jun 14 '19 at 07:17
  • @divine To clarify: are the created and mounted hooks called server side in nuxt? If so, the only reason to use asyncData would be timing. – Robot Jul 19 '19 at 18:27
  • To emphasize: `asyncData` is only in 'pages' not in 'components.' Must use `fetch` in that one. Strangely, when making this mistake of using `asyncData` in a 'components' file, there is no warning or linting error. ‍♂️ – CodeFinity Jul 22 '20 at 12:45
  • But doesn't fetch has access to component context with `this`? Then it can set data like this.someData = data; -> `With the help of this context, fetch is able to mutate component’s data directly.` – Vedmant Dec 23 '20 at 10:53
  • > "yes correct, in spa whatever goes into asyncData or fetch will be invoked first then created hook gets invoked" - if you check update in nuxt 2.12 fetch() is called after create() – Vedmant Dec 23 '20 at 10:54
7

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
Tamlyn
  • 18,041
  • 10
  • 96
  • 117
  • 1
    That said, in a SSG site we "should" use ```asyncData``` for retrieving data for a page that will not change during navigation and, for example, set the dynamic meta tags in the head method (if using ```fetch()```, ```head()``` could not receive the data in time). We should use ```fetch()``` when we want more control on the data received, for example if there is a button to trigger the ```fetch()``` again while showing a placeholder with ```$fetchState.pending```. Am I thinking it right? – Stefano Franceschetto Feb 25 '21 at 09:26
  • @StefanoFranceschetto makes sense – Marian Klühspies Mar 29 '21 at 20:07
  • The section on "loading" really clarifies things for me. – Shawn Lauzon May 15 '21 at 08:35
6

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.

Bhargav Rao
  • 41,091
  • 27
  • 112
  • 129
kp123
  • 574
  • 9
  • 15
4

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>
HoangYell
  • 1,967
  • 22
  • 21