getElementsByClassName after loop with VueJS

I’m using VueJS and i’m trying to loop on html elements after loop.

First i use worpress API to get categories then posts by categories.

I have exactly 5 categories in my database.

I have no v-if on my code, maybe i can’t loop because my DOM is not ready with my v-for ?

I don’t understand why i can’t loop my elements.

<template>
  <div id="tutos">
    <div
      v-for="(tuto, index) in tutos"
      :id="tuto.categorie_slug"
      :key="index"
      class="row"
    >
      <div class="tutos-list"></div>
    </div>
  </div>
</template>

<script>
export default {
  name: "Tutos",
  data() {
    return {
      tutos: [],
    };
  },
  methods: {
    getCategories: async function () {
      const categories = await this.axios.get("/categories");
      return categories.data;
    },
    getPosts: async function (id) {
      const posts = await this.axios.get("/posts?categories=" + id);
      return posts.data;
    },
  },
  mounted: async function () {
    // Load datas
    await this.getCategories().then((data) => {
      Array.from(data).forEach((categorie) => {
        if (categorie.count > 0) {
          this.getPosts(categorie.id).then((posts) => {
            this.tutos.push({
              categorie_name: categorie.name,
              categorie_slug: categorie.slug,
              posts: posts,
            });
          });
        }
      });
    });

    // Wait For DOM
    await this.$nextTick();

    const tutos_list = document.getElementsByClassName("tutos-list");
    // Log an HTMLCollection with 5 children
    console.log(tutos_list);

    // Loop Nothing
    Array.from(tutos_list).forEach((list) => {
      console.log(list);
    });
  },
};
</script>

<style lang="scss">...</style>

UPDATE SCREEN

Devtools and console screen

Thanks a lot 🙂

>Solution :

The part that loads the data is not awaiting the individual calls to getPosts, and the promise returned by the this.getCategories().then() call is immediately resolved, as there is no explicit return statement in its callback that returns a promise. By consequence this part of your code finishes before any entries have been added with push. Those push calls happen in a then callback that will execute later. Your code doesn’t do anything with the promises that these inner this.getPosts(categorie.id).then() calls return.

You could use Promise.all to await all those getPosts promises as follows:

    // Load datas
    this.tutos.push(...await this.getCategories().then(data =>
      Promise.all(
        [...data].filter(categorie => 
          categorie.count > 0
        ).map(async categorie => ({
          categorie_name: categorie.name,
          categorie_slug: categorie.slug,
          posts: await this.getPosts(categorie.id)
        }))
      )
    ));

Leave a Reply