Reputation: 47
I am learning Vue Js and I want to develop a small application with which I bring different data according to what I select in a dropdown.
The problem I am having is that when I want to see what I am bringing (by console) with a computed property, it shows me 'promise {', which inside it is the data with which I want to work, but being in 'pending' I can't extract and use them.
This is the application that I have developed so far, which brings news depending on the section that is entered:
<template>
<div>
<div v-for="new in totalNews" :key="new.id">
</div>
</div>
</template>
<script>
export default {
name: "Home",
data() {
return {
news: [],
};
},
methods: {
async getNews() {
const param = this.$route.params.id;
await this.axios
.get("http://localhost:8080/api/v1/newsBySelection/" + id)
.then((res) => {
this.news = res.data;
})
.catch((error) => {
console.log(error);
});
},
computed: {
totalNews() {
let news = this.getNews()
console.log(news);
return news;
},
},
};
</script>
Here is a sample of what I get on the console when running this application, as you can see every time I select a section of the diamond brings me the corresponding news, but in the form of promises:
https://i.postimg.cc/XqtHBZfL/imagenparasubir.png
I already appreciate any kind of help !!
Upvotes: 2
Views: 2430
Reputation: 8329
This is not really a Vue question, but a general Javascript topic: how do asynchronous calls work, what is a Promise
& how does async/await
simplify the syntax.
Here's a small snippet to show you a possible solution using Promise
to display a list of items obtained from an API endpoint:
new Vue({
el: "#app",
data() {
return {
// we init a variable that is going to hold
// the values that we expect to receive from
// the API endpoint
news: [],
}
},
methods: {
getNews() {
fetch('https://jsonplaceholder.typicode.com/todos')
.then(response => response.json())
.then(json => {
// the data is added to our component data
// when it arrives from the API endpoint
this.news = json
})
},
},
mounted() {
// we query the API endpoint when the component
// is mounted in the DOM
this.getNews()
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="article in news" :key="article.id">
{{ article.title }}
</div>
</div>
There's one implicit thing in the snippet: why is it a solution using Promise
? Where's the Promise
in the snippet?
[fetch] returns a Promise that resolves to the Response to that request
Source: MDN Fetch API
This is why we can use .then()
after fetch()
- fetch
always returns a Promise
.
Upvotes: 0
Reputation: 5118
getNews
is an async
function. Although it doesn't actually return
anything, it being async means it's a Promise
. What's happening in your totalNews
computed is that you're getting the promise object which represents this.getNews()
, so the behavior you're seeing makes sense. Your computed probably should not be calling a method that modifies the component's state. The point of a computed is to return a value based on one or more properties in the component.
Instead, call this.getNews()
in the mounted
lifecycle hook:
<script>
export default {
name: "Home",
// ...
mounted() {
this.getNews()
}
}
</script>
There's no need to use a computed at all here, because you just want to display all the objects in the data. So this becomes:
<template>
<div>
<div v-for="item in news" :key="item.id">
</div>
</div>
</template>
I also changed new
to item
, because new
is actually a keyword in JavaScript.
Update
It's fine to use computed properties if you want to filter based on a user selection. Something such as this:
computed: {
filteredNews() {
return this.news.filter(item => item.someProperty === this.selectedOption);
}
}
Upvotes: 2
Reputation: 1414
You'll probably benefit from reading how Promise object works conceptually.
To your purpose, you might find using the .then() method useful - it essentially will call back to the code inside after the promise has resolved.
Because you are using an async function, the work is on a separate thread. If you are trying to get the value in a separate thread, it won't know when the data has been loaded.
Upvotes: 1