2

Thank you in advance.

So I am fetching list of blog categories via API and rendering it in a list using v-for.

I also need to fetch the amount of blogs in every category and place them beside the category.

But the issue is I am calling a method that calls the api.

   <li v-for="item in sidebar" :key="item.identifier">
        <nuxt-link
          tag="a"
          :to="{
            name: 'blog-page',
            query: { category: item.identifier }
          }"
          >{{ $localize(item.translations).title }}
          {{ getBlogCount(item.identifier) }}
        </nuxt-link>
   </li>

You know what it shows already example is Animals [Object Promise]

  methods: {
    async getBlogCount(identifier) {
      axios
        .get(
          "https://example.com/posts?fields=created_at&filter[category.category_id.identifier]=" +
            identifier +
            "&meta=*"
        )
        .then(count => {
          return count.data.meta.result_count;
        });
    }
  }

What is the best way to handle this kinda thing?

Node Shack
  • 59
  • 6

2 Answers2

3

You better call async methods in mounted or created hooks, and set the result to data, and then, use that data in template.

Davud Safarov
  • 498
  • 4
  • 12
0

I'd suggest handling this in Script, instead of HTML Template.

What you can do is, depending on when the sidebar is initialized (maybe in the mounted hook), call getBlogCount method to fetch blog counts for each item in sidebar and store that may be in an array or object (or as a separate key-value pair to that same sidebar item object) and then use that data structure to display count values in the template.

Assuming the sidebar is populated in mounted hook and that it's an array of objects, you can do the following:

<template>
   <li v-for="item in sidebar" :key="item.identifier">
        <nuxt-link
          tag="a"
          :to="{
            name: 'blog-page',
            query: { category: item.identifier }
          }"
          >{{ $localize(item.translations).title }}
          {{ item.blogCount }}
        </nuxt-link>
   </li>
</template>

<script>
mounted () {
  // after the sidebar is populated
  this.sidebar = this.sidebar.map(async item => {
    item.blogCount = await this.getBlogCount(item.identifier)
    return item
  })
}
</script>

Hope this helps you out

waleed ali
  • 1,175
  • 10
  • 23
  • why is that so? – waleed ali Jul 20 '20 at 06:01
  • well, first of all you using `await` in an non async function `(item => {` should be `(async item => {`. After this you should wrap everything in an `Promis.all()` read about it https://stackoverflow.com/questions/40140149/use-async-await-with-array-map – bill.gates Jul 20 '20 at 06:04
  • yes, callback should be an async function. but I don't think we need to wrap this up in Promise.all() – waleed ali Jul 20 '20 at 06:06
  • in the answer you shared, the callee function may not be returning a Promise (also explained in that answer). but here, `getBlogCount` itself is an async function, which does return a Promise. so we don't need to wrap this up in Promise.all() – waleed ali Jul 20 '20 at 06:10
  • `async` functions are returning an promise. that means that `this.sidebar` is an array with pending promises. for that you need to wrap it in `Promise.all()` – bill.gates Jul 20 '20 at 06:23