3

I've seen quite a few ways of doing this. I wanted originally to store the image and call it from my database to the view, but I'm not sure where I should store it and the correct way to call it (:src="prizes.image_url")??

The image is stored client-side

{
    id: 2,
    name: "Merano MC400 Cello",
    description: "Established in 2000, Merano have made it their mission to create affordable, beautifully crafted instruments. They offer brass, wind and stringed instruments all at reasonable prices. They have a large team of artisans who look over every instrument to ensure it maintains high standards. Many of their instruments are aimed at the beginner market but they also offer some fine examples of professional equipment as well.",
    image_url: "../assets/images/c5Cor.png",
    quantity: 3
}
getPrizes() {
  axios.get('http://localhost:3000/prizes').then(response => {
    this.prizes = response.data
    console.log(response.data)
  })
}
<div v-for="prize in prizes" :key="prize.id">
   <div class="card_individual">
      <div class="card-media-container">
         <img class="card_image" :src="prize.image_url" alt="instruments"/>
      </div>
      <div class="card-detail-container">
         <div class="card_title">Win a {{ prize.name }}</div>
      </div>
      <div class="modal-footer">
         <router-link :to="{ name: 'PriceDetail', params: { prizeId: prize.id }}"><button type="button" class="btn btn-primary">{{ cards.btn_text }}</button></router-link>
      </div>
   </div>
</div>
Dan
  • 59,490
  • 13
  • 101
  • 110
  • Can you include the rest of your component, especially the initialization of the component and the part where `getPrizes` is called? – Emiel Zuurbier Feb 26 '20 at 18:57
  • Are you asking how to store your image in a database, or how to display that image in your Vue component? – Emiel Zuurbier Feb 26 '20 at 18:58
  • @EmielZuurbier Well, the rest of the items stored in my database come up just fine, but I don't know if I should be storing the images in the client-side, or server-side. Also, how to display them. The images themselves are stored in the wrong place I'm assuming? –  Feb 26 '20 at 19:03
  • Images should be stored on the server, as they will be downloaded to the client when they are needed. Right now your localhost functions as a server and the images are retrieved from there. A database could have a record leading to the URL of your image, but the image itself would not be stored there. When you call `getPrizes` does the template re-render correctly (aside from the image)? – Emiel Zuurbier Feb 26 '20 at 19:13
  • @EmielZuurbier Yes. Everything else renders perfectly. I tried storing an image in server/public/images but that didn't work. Although, I'm wondering if I got the path wrong... –  Feb 26 '20 at 19:15
  • You need to create a blob from it – deathangel908 Feb 26 '20 at 19:15
  • You lost me there @deathangel908. A blob? –  Feb 26 '20 at 19:20
  • @EmielZuurbier I should mention that I'll be uploading this to Heroku after, so I'm also wondering if that will affect this in any way. –  Feb 26 '20 at 19:21

2 Answers2

1

Short answer

Put all of your images in the assets directory (or a subdirectory). Store just the filename in your JSON like image_url: "c5Cor.png" and show it like:

<img :src="require('@/assets/' + prize.image_url)" />

Other comments

Webpack bundles the assets folder, which renames the paths/filenames of the contents. So that's why require is needed-- when binding src to a variable-- to get the correct path at runtime.

When you say client/server, you may mean frontend/backend. Those are different because both frontend and backend resources are served from the server. For example, this statement, "The image is stored client-side": unless you've stored the image in localStorage, indexedDB, etc, is inaccurate. Storing the images in Vue's assets directory is server-side frontend. The database would be server-side backend.

So unless you intended to ask about storing images in localStorage, better phrasing might be, "Should I store images in the database or as files?". On a typical website, you would store the images as files, and store just the filenames in your database. (It is possible to store raw images' binary data in the database-- a blob-- and there's some debate about when this is a good idea, but it's probably statistically rare in typical websites.) It's easier to store them as files.

Dan
  • 59,490
  • 13
  • 101
  • 110
  • 1
    That's exactly what I meant. Thanks for clearing that up for me, it's always a been a bit confusing to me. I assume that the "assets" directory will be server-side backend and not frontend? –  Feb 26 '20 at 20:40
  • You're welcome. `assets` and all of the visual, interactive elements constitute the frontend. Backend typically refers to the host OS and tech including web server (Node, Apache, etc), database, and any server-side computing (also Node, PHP, etc.) that isn't immediately interactive. I'm improvising those definitions, I'm sure there are much better ones out there. – Dan Feb 26 '20 at 21:08
0

Query the img and assign it as blob:

<img class="card_image" :src="getImageBlob(prize.image_url)" alt="instruments"/>
  <div v-for="prize in prizes" :key="prize.id">
    <div class="card_individual">
      <div class="card-media-container">
        <img class="card_image" :src="getImageBlob(prize.image_url)" alt="instruments"/></div>
      <div class="card-detail-container">
        <div class="card_title">Win a {{ prize.name }}</div>
      </div>
      <div class="modal-footer">
        <router-link :to="{ name: 'PriceDetail', params: { prizeId: prize.id }}"><button type="button" class="btn btn-primary">{{ cards.btn_text }}</button></router-link>
      </div>
    </div>
  </div>
  getPrizes () {
    axios.get('http://localhost:3000/prizes')
      .then(response => (this.prizes = response.data)
  },
  getImageBlob (image_url) {
    return axios.get(image_url).then(response => window.URL.createObjectURL(response.data))
  }

The same way if you want to store it in your database you can store the response.data in your database too.

juanesarango
  • 560
  • 9
  • 17