[Vuejs]-Vue js function countSubcategories() returns [object Promise]

1šŸ‘

As Aron stated in the previous answer as you are calling direct from the template the information is not ready when the template is rendered.

As far as I understood you need to run getCategories first so then you can fetch the rest of your data, right?

If thatā€™s the case I have a suggestion:

Send an array of cat ids to your back-end and there you could send back the list of subcategories you need, this and this one are good resources so read.

And instead of having 2 getCategories and countSubcategories you could ā€œmergeā€ then like this:

fetchCategoriesAndSubcategories(page) {
  if (typeof page === "undefined") {
    page = 1;
  }
  let url = helper.getFilterURL(this.filterpartnerForm);
  axios
    .get("/api/get-user-permission-categories?page=" + page + url)
    .then(response => {
      this.cats = response.data;
      let catIds = this.cats.map(cat => (cat.id));
      return this.countSubcategories(catIds) // dont forget to change your  REST endpoint to manage receiving an array of ids 
    })
    .then(response => {
      this.childcounts = response.data
    });
}

Promises allow you to return promises within and chain .then methods

So in your created() you could just call this.fetchCategoriesAndSubcategories passing the data you need. Also you can update your template by adding a v-if so it doesnā€™t throw an error while the promise didnā€™t finish loading. something like this:

<div v-if="childCounts" v-for="(subcategorie, index) in childCounts" :key="subcategorie.id">

  {{ subcategorie }}  // Here subcategories row counts should be displayed.

 </div> 
šŸ‘¤brunobraga

0šŸ‘

This is happen ā€™cause youā€™re trying to render a information who doesnā€™t comeback yetā€¦

Try to change this method inside created, make it async and donā€™t call directly your method on HTML. Them you can render your variable this.childcounts.

šŸ‘¤Aron Richter

0šŸ‘

Hello!

Based on the provided information, it could be 2 things. First of all, you may try replacing:

return response.data;

with:

console.log(this.childcounts)

and look in the console if you have the correct information logged. If not, it may be the way you send the information from Laravel.

PS: More information may be needed to solve this. When are you triggering the ā€˜countSubcategoriesā€™ method?

šŸ‘¤uatar

0šŸ‘

I would do all the intial login in the component itself, and not call a function in template like that. It can drastically affect the performance of the app, since the function would be called on change detection. But first, you are getting [object Promise], since that is exactly what you return, a Promise.

So as already mentioned, I would do the login in the component and then display a property in template. So I suggest the following:

methods: {
  countSubcategories(id) {
    return axios.get("..." + id);
  },

  getCategories(page) {
    if (typeof page === "undefined") {
      page = 1;
    }

    // or use async await pattern
    axios.get("...").then(response => {
      this.cats = response.data;
      // gather all nested requests and perform in parallel
      const reqs = this.cats.map(y => this.countSubcategories(y.id));
      axios.all(reqs).then(y => {
        // merge data
        this.cats = this.cats.map((item, i) => {
          return {...item, count: y[i].data}
        })
      });
    });
  }
}

Now you can display {{cat.count}} in template.

Hereā€™s a sample SANDBOX with similar setup.

šŸ‘¤AT82

Leave a comment