I am calling an async function which loads the profile pic, the await call returns the value to the variable 'pf' as expected, but I couldn't return that from loadProfilePic. At least for the start I tried to return a static string to be displayed as [object Promise]
in vue template.
But when I remove await/asnyc it returns the string though.
<div v-for="i in obj">
{{ loadProfilePic(i.id) }}
</div>
loadProfilePic: async function(id) {
var pf = await this.blockstack.lookupProfile(id)
return 'test data';
//return pf.image[0]['contentUrl']
},
Render is sync. You should call this method from created or some other suitable lifecycle hook and save the result in component’s data, then render that data. I’ve found vue-promised plugin, could it be solution? Possibly, yes. But you should definitely not call the async method from within the template, it would result in an endless loop2
When you mark the method as async it will return a promise, so, its pointless to return a promise and mark it as async at same time. You should await the async method or promise from created or some other suitable lifecycle hook and save the result in component’s data, then render that data.
There are a few good methods of handling async data in Vue. Call a method that fetches the data in the created lifecycle hook that assigns it to a data property. This means that your component has a method for fetching the data and a data property for storing it. Dispatch a Vuex action that fetches the data.
Call a method that fetches the data in the created lifecycle hook that assigns it to a data property. This means that your component has a method for fetching the data and a data property for storing it. Dispatch a Vuex action that fetches the data.
That is because async function
returns a native promise, so the loadProfilePic
method actually returns a promise instead of a value. What you can do instead, is actually set an empty profile pic in obj
, and then populate it in your loadProfilePic
method. VueJS will automatically re-render when the obj.profilePic
is updated.
<div v-for="i in obj">
{{ i.profilePic }}
</div>
loadProfilePic: async function(id) {
var pf = await this.blockstack.lookupProfile(id);
this.obj.filter(o => o.id).forEach(o => o.profilePic = pf);
}
See proof-of-concept below:
new Vue({
el: '#app',
data: {
obj: [{
id: 1,
profilePic: null
},
{
id: 2,
profilePic: null
},
{
id: 3,
profilePic: null
}]
},
methods: {
loadProfilePic: async function(id) {
var pf = await this.dummyFetch(id);
this.obj.filter(o => o.id === id).forEach(o => o.profilePic = pf.name);
},
dummyFetch: async function(id) {
return await fetch(`https://jsonplaceholder.typicode.com/users/${id}`).then(r => r.json());
}
},
mounted: function() {
this.obj.forEach(o => this.loadProfilePic(o.id));
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="i in obj">
{{ i.profilePic }}
</div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With