0

I'm still new to VueJS, and I cannot figure this one out.

I have a page that loads with axios from wordpress my posts:

export default {
  data() {
    return {
      postsUrl: "https://localhost/wordpress/wp-json/wp/v2/news",

      posts: [] as any[],
      isLoading: false,
      regex: /(<([^>]+)>)/gi,
      errorCaught: false,
    };
  },
  methods: {
    getPosts() {
      this.isLoading = true;
      axios
        .get(this.postsUrl, { params: { _embed: true } })
        .then((response) => {
          this.posts = response.data;
          console.log("Pages retrieved!");
          console.log(this.posts);
          this.isLoading = false;
        })
        .catch((error) => {
          console.log(error);
          if (error) {
            this.isLoading = false;
            setTimeout(() => {
              this.errorCaught = true;
            }, 1100);
          }
        });
    },
  },
  mounted() {
    this.getPosts();
  },
};

and the template

<template>
  <div class="news-container">
    <div class="loading">
      <transition name="fadeLoading">
        <div v-if="isLoading">Loading...</div>
      </transition>
      <transition name="fadeLoading">
        <div v-if="errorCaught">There was an error loading news</div>
      </transition>
    </div>
    <ul v-for="(index) in posts"  :key="index" ref="posts">
      <h1>
        <router-link :to="index.slug" tag="div" key="page.id"
          >{{ index.title.rendered }}
        </router-link>
      </h1>
      <img
        v-if="index._embedded['wp:featuredmedia']"
        :src="index._embedded['wp:featuredmedia'][0].source_url"
      />

      <p class="date">{{ index.date }}</p>
    </ul>
  </div>
</template>

This works fine, no problem with the Options API.

But when I want to convert this to the Composition API, the posts don't appear:

<script setup lang="ts">
import axios from "axios";
import { ref } from "vue";
import { onMounted } from "vue";

const postsUrl = "https://localhost/wordpress/wp-json/wp/v2/news";

var posts = ref([] as any);
const isLoading = ref(false);
const regex = /(<([^>]+)>)/gi;
const errorCaught = ref(false);

const getPosts = () => {
  isLoading.value = true;
  axios
    .get(postsUrl, { params: { _embed: true, page: 1 } })
    .then((response) => {
      posts = response.data;
      console.log("Pages retrieved!");
      console.log(posts);
      isLoading.value = false;
    })
    .catch((error) => {
      console.log(error);
      if (error) {
        errorCaught.value = true;
      }
    });
};

onMounted(() => {
  getPosts();
});
</script>

I suspect there is a misunderstanding on my part how refs work, because If I edit the <template> (and have npm run dev running the server), I can see that the posts appear.

Could you help me with what am I doing wrong and why? Thank you for your time

1 Answer 1

1

Your mistake is here

posts = response.data;

When you use ref you have to use it with value. Change your code to this:

posts.value = response.data;

It should be working fine. For more detail you should check here:

https://vuejs.org/api/reactivity-core.html#ref

2
  • Wow, how did I miss that when I used it on isLoading and errorCaught properly, thx! On the other hand, now there is an error: TypeError: Cannot read properties of undefined (reading 'wp:featuredmedia') Only the featuredmedia throws this, other divs with dot notations are fine. Also, this error does not show if I use Options API.
    – Larry
    Commented Jan 5, 2023 at 13:21
  • Oh and to be perfectly clear, even thought there IS this error showing in console, the images DO STILL get loaded fine.
    – Larry
    Commented Jan 5, 2023 at 13:23

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.