0

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 :)

9
  • Log the tutos in the console. Don't forget to use Vue devtools to check what are the values of tutos. devtools.vuejs.org Commented Nov 23, 2022 at 10:05
  • I console log tutos just after nextTick and it return a Proxy with my 5 children in [[Target]]. And in my Vue devtools, i see my tutos var with children as well. Commented Nov 23, 2022 at 10:11
  • Upload a picture of tutos logged on console or vue devtools. Commented Nov 23, 2022 at 10:12
  • Just did it on my post Commented Nov 23, 2022 at 10:16
  • Yeah currently my template render well my categories and my posts {{ categorie_name }} display my categorie name. Commented Nov 23, 2022 at 10:19

1 Answer 1

1

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)
        }))
      )
    ));
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot, it works !! I will study your code to understand everything.

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.