Fetch only works on refresh

Viewed 2183

I am trying the new Nuxt.js Fetch method. Initially, I thought everything was fine. But the data is only fetched and rendered when I refresh the page. However, if the page is accesses through $fetchState.error equals true and the data is never fetched.

What am I doing wrong here?

<template>
  <main>
    <div>
      <div>
        <p v-if="$fetchState.pending">
          Fetching vehicles...
        </p>
        <p v-else-if="$fetchState.error">
          Error while fetching vehicles
        </p>
        <div
          v-for="(vehicle, index) in usedVehicles"
          v-else
          :key="index"
        >
          <nuxt-link :to="`cars/${vehicle.Id}`">
            {{ vehicle.Make }}
          </nuxt-link>
        </div>
      </div>
      <button @click="$fetch">Refresh Data</button>
    </div>
  </main>
</template>

<script>
import axios from 'axios'

export default {
  data() {
    return {
      usedVehicles: []
    }
  },
  async fetch() {
    const { data } = await axios.get(
      'https://random.com/api'
    )
    // `todos` has to be declared in data()
    this.usedVehicles = data.Vehicles
  },
  methods: {
    refresh() {
      this.$fetch()
    }
  }
}
</script>


1 Answers

Just answered a related question re: fetch

So in the lifecycle hooks,

The fetch is called (but only finishes after the page is mounted). This means that when you refresh the page, the data should be cached on the client side (hence renders the this.usedVehicles).

If you want to ensure that the data is retrieved before the first mount, you can use asyncData and await the call - such that usedVehicles is set before the page is mounted.

example

<template>
  <main>
    <div>
      <div>
        <p v-if="$fetchState.pending">
          Fetching vehicles...
        </p>
        <p v-else-if="$fetchState.error">
          Error while fetching vehicles
        </p>
        <div
          v-for="(vehicle, index) in usedVehicles"
          v-else
          :key="index"
        >
          <nuxt-link :to="`cars/${vehicle.Id}`">
            {{ vehicle.Make }}
          </nuxt-link>
        </div>
      </div>
      <button @click="$fetch">Refresh Data</button>
    </div>
  </main>
</template>

<script>
import axios from 'axios'

export default {
  data() {
    return {
      usedVehicles: []
    }
  },
  async asyncData() {
    const { data } = await axios.get(
      'https://random.com/api'
    )

    return { usedVehicles: data.Vehicles }
  }
  async fetch() {
    const { data } = await axios.get(
      'https://random.com/api'
    )
    // `todos` has to be declared in data()
    this.usedVehicles = data.Vehicles
  },
  methods: {
    refresh() {
      this.$fetch()
    }
  }
}
</script>

This will mean that on each request, theres going to be some delay to retrieve that data - but it depends if that is your desired result.

lifecyclehooks

Related