7

This is my example:

<template>
  <div v-for="id of SomethingChanging">
    {{ getSomethingAsync(id) }}
  </div>
</template>

<script>
export default {
  ...
  methods:{
   async getSomethingAsync(id){
      try {
        const result = await getSomethingAPI(id)
        return result.payload
      } catch (e) {
        console.log(e)
      }
    }
  }
}
</script>

All we know, ​async function will return a promising object ...

How can I fix it so that the page will return the truly data?

3
  • 1
    The question doesn't contain enough details. Is it Vue 2 or 3? Vue 3 has suspense. What is the real case? id in 5 looks like bogus code. It's unclear why you couldn't fetch data on mount. Commented Jun 30, 2021 at 16:05
  • Thank you all. But i still dont know why couldnt vue2 template use async function directly?Could Vue 3 use async function directly in template and get result directly? Commented Jun 30, 2021 at 16:19
  • Because this isn't how Vue works. Promise object is a promise of a result, not a result itself, supporting them in templates would require the framework to work very differently than it works now. No, in Vue 3 you couldn't do this too but could use async setup(...) and the value would be available at the time when a template is rendered Commented Jun 30, 2021 at 16:34

1 Answer 1

8

Don't try to call methods inside template to render something, because this could give some issues like infinite rendering, instead of that you can define a data property that you can fill it inside the created hook like :

<template>
  <div v-for="item in result">
    {{ item }}
  </div>
</template>

<script>
export default {
  ...
 data() {
    return {
      result: []
    }
  },
  methods: {
    async getSomethingAsync(id) {
      try {
        const result = await axios.get('https://jsonplaceholder.typicode.com/todos/' + id)

        return result.data
      } catch (e) {
        console.log(e)
      }
    }
  },
  async created() {
    this.result = await Promise.all([...Array(5)].map((_, i) => {
      return this.getSomethingAsync(i + 1)
    }))
  }
</script>

Example

// ignore the following two lines, they just disable warnings in "Run code snippet"
Vue.config.devtools = false;
Vue.config.productionTip = false;

new Vue({
  el: '#app',
  data() {
    return {
      result: []
    }
  },
  methods: {
    async getSomethingAsync(id) {
      try {
        const result = await axios.get('https://jsonplaceholder.typicode.com/todos/' + id)

        return result.data
      } catch (e) {
        console.log(e)
      }
    }
  },
  async created() {
    this.result = await Promise.all([...Array(5)].map((_, i) => {
      return this.getSomethingAsync(i + 1)
    }))
  }
})
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title></title>
  <link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />

  <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <script src="https://unpkg.com/[email protected]/dist/vue-axios.min.js"></script>
</head>

<body>
  <div id="app">
    <ul>
      <li v-for="item in result">
        {{ item.title }}
      </li>
    </ul>
  </div>
</body>

</html>

Sign up to request clarification or add additional context in comments.

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.