24

I'm interesting in the case of displaying in vue template data which loaded asynchroniously. In my particular situation I need to show title attribute of product object:

<td class="deals__cell deals__cell_title">{{ getProduct(deal.metal).title }}</td>

But the product isn't currently loaded so that the title isn't rendered at all. I found a working solution: if the products aren't loaded then recall getProduct function after the promise will be resolved:

getProduct (id) {
  if (!this.rolledMetal.all.length) {
    this.getRolledMetal()
      .then(() => {
        this.getProduct(id)
      })
    return {
      title: ''
    }
  } else {
      return this.getRolledMetalById(id)
  }
}

However maybe you know more elegant solution because I think this one is a little bit sophisticated :)

2 Answers 2

37

I always use a loader or a spinner when data is loading!

<template>
  <table>
    <thead>
      <tr>
        <th>One</th>
        <th>Two</th>
        <th>Three</th>
      </tr>
    </thead>
    <tbody>

      <template v-if="loading">
        <spinner></spinner> <!-- here use a loaded you prefer -->
      </template>

      <template v-else>
        <tr v-for="row in rows">
          <td>{{ row.name }}</td>
          <td>{{ row.lastName }}</td>
        </tr>
      </template>

    </tbody>
  </table>
</template>

And the script:

<script>
  import axios from 'axios'
  export default {
    data() {
      return {
        loading: false,
        rows: []
      }
    },
    created() {
      this.getDataFromApi()
    },
    methods: {
      getDataFromApi() {
        this.loading = true
        axios.get('/youApiUrl')
        .then(response => {
          this.loading = false
          this.rows = response.data
        })
        .catch(error => {
          this.loading = false
          console.log(error)
        })
      }
    }
  }
</script>
Sign up to request clarification or add additional context in comments.

2 Comments

what happend if the getDataFromApi function is async ? does it make any difference?
@KickButtowski nah it can be async and everything will work fine. You just have to use await in the axios call + you can get rid of .then & .catch
8

There are a few good methods of handling async data in Vue.

  1. Call a method that fetches the data in the created lifecycle hook that assigns it to a data property. This means that your component has a method for fetching the data and a data property for storing it.

  2. Dispatch a Vuex action that fetches the data. The component has a computed property that gets the data from Vuex. This means that the function for fetching the data is in Vuex and your component has a computed property for accessing it.

In this case, it looks like your component needs to have a RolledMetal and based on that it retrieves a product. To solve this you can add methods that fetch both of them, and call them on the created lifecycle. The second method should be called in a then-block after the first one to ensure it works as expected.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.