Its Andrew
Its Andrew

Reputation: 155

Vue / Nuxt.js - APIs being called twice in created hook

I am currently developing in Nuxt.js and like most beginners, I wanted to know the best lifecycle hook to place API calls. Many resources I have found, much like the one below, state that the created() hook is the best place for fetching data from an API prior to having everything be loaded.

Difference between the created and mounted events in Vue.js

My question came in when I noticed on the networking tab in developer options that my API within the created() hook was being called twice. After looking into this further, it states that this hook runs on server side and client side. I notice that mounted() only runs on client side so I am learning towards utilizing that hook. I did however notice that I can use some if logic (if process.server) in the created() hook to only have this run on the client / server and not both. Is this a common solution?

To clarify my question further, if created() runs on both server and client side, why put my API calls in this hook?

Upvotes: 3

Views: 3592

Answers (1)

tony19
tony19

Reputation: 138326

While created might be an appropriate hook for Vue apps, Nuxt provides additional hooks that are better suited for fetching data. If you need the fetch to occur only on the server side, the call would need to be wrapped with if(process.server) within the hook.

fetch hook

  1. Called during server-side rendering after the component instance is created, and on the client when navigating, but the server-side fetch can be disabled with fetchOnServer: false.
  2. Available in all Vue components
  3. this context is available
  4. Simply mutates the local data
  5. Exposes the data loading status via $fetchState.pending and $fetchState.error, and allows manually invoking the fetch hook with $fetch()

Example usage:

export default {
  data() {
    return {
      todos: []
    }
  },
  async fetch() {
    const { data } = await axios.get(
      `https://jsonplaceholder.typicode.com/todos`
    )
    // `todos` has to be declared in data()
    this.todos = data
  }
}

asyncData hook

  1. Called before the component instance is created
  2. Limited to only page-level components
  3. this context is unavailable
  4. Adds payload by returning the data

Example usage:

export default {
  async asyncData(context) {
    const data = await context.$axios.$get(
      `https://jsonplaceholder.typicode.com/todos`
    )
    // `todos` does not have to be declared in data()
    return { todos: data.Item }
    // `todos` is merged with local data
  }
}

Upvotes: 5

Related Questions