mrks
mrks

Reputation: 5611

Vue.js: Return image with method after axios.get

<li v-for="people in projectData.employees" :key="people._id">
    <b-img :src="colleagueImages(people)" 
</li>
async colleagueImages(people) {
  console.log(people); // => [email protected]
  let profileImage = await axios.get("http://myapilink.com/image?id=" + people + "&s=200&def=avatar", {
    headers: {
      'accept': 'image/jpeg'
    }
  });
  console.log(profileImage);
  return 'data:image/jpeg;base64,' + btoa(
    new Uint8Array(profileImage.data)
    .reduce((data, byte) => data + String.fromCharCode(byte), '')
  );
}

The console.log(profileImage) returns the following:

Chrome console.log The API I am using is returning a Base64 Image.

With my current code I only get the following error in my browser console:

[Vue warn]: Invalid prop: type check failed for prop "src". Expected String, got Promise.

Upvotes: 0

Views: 2610

Answers (1)

pongi
pongi

Reputation: 399

Since you don't have all the data you need to render in the first place, you have to change attributes afterwards. First, you need to use Vue components for your items, so your "src" attribute will be reactive; second, you start the requests for your items after you rendered your app. Please see this mockup.

Vue.component('todo-item', {
  template: `
    <li>
      <label>
        <input type="checkbox"
          v-on:change="toggle()"
          v-bind:checked="done">
        <del v-if="done">
          {{ text }}
        </del>
        <span v-else>
          {{ text }}
        </span>

        <span v-if="like">
            ♥ {{like}}
        </span>
      </label>
    </li>
    `,
  props: ['id', 'text', 'done', 'like'],
  methods: {
    toggle: function(){
        this.done = !this.done
    }
  }
})
let todos = [
      {id: 0, text: "Learn JavaScript", done: false, like: null },
      {id: 1, text: "Learn Vue", done: false, like: null },
      {id: 2, text: "Play around in JSFiddle", done: true, like: null },
      {id: 3, text: "Build something awesome", done: true, like: null }
    ]
const v = new Vue({
  el: "#app",
  data: {
    todos: todos
  }
})

todos.forEach((item) => {
    // This is just a mock for an actual network request
    window.setTimeout(() => {
        item.like = Math.ceil(Math.random() * 100)
    }, Math.random() * 2000)
})

https://jsfiddle.net/willywongi/gsLqda2y/20/

In this example I have the basic todo-list app with a fake "like" count for each item, which is calculated asynchronously. After setting up my app, I wait for the "like" attribute values (in my example I just wait a random value of milliseconds).

Upvotes: 1

Related Questions