Jacob Hixon
Jacob Hixon

Reputation: 153

Dynamic img src URL with "OR" statement not working properly in NUXT component

I am trying to render an image src path dynamically based on the prop provided to the component, and provide a fallback path if that image doesn't exist in the assets folder. Here is my image tag:

<img 
  :src="require(`@/assets/${project.image || 'day-1.jpg'}`)" 
  alt="project image"
  class="rounded-xl row-span-3 col-span-1"
>

For the first instance of this component on the site, {project.image} should (and does) provide the proper image file name from the store: gfs.jpg (an image that does not exist in the file tree)

In this case, shouldn't my code above tell Webpack to render the day-1.jpg image, due to the || or operator being used, since the file at gfs.jpg is not found?

Webpack is throwing the error Cannot find module './gfs.jpg' with error code 500

I also tried using an @error tag that calls a handler function from methods: {}, but that doesn't fire when this error occurs.

Upvotes: 2

Views: 3294

Answers (2)

kissu
kissu

Reputation: 46604

This is how I could write it:

<template>
  <div>
    <img :src="require(`@/assets/${chosen}`)" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      project: {
        image: 'gfs.jpg', // test this with '' (empty string)
      }
    }
  },
  computed: {
    chosen() {
       // optional chaining (?.) could be a nice fallback for your project
      return this.project?.image || 'day-1.jpg'
    },
  },
}
</script>

If you mistake some images or your server refreshes too quickly, you may have some weird errors in the console and fastest way would be to restart the server.

Also, more answers can be found here: Vue.js dynamic images not working

Upvotes: 0

tony19
tony19

Reputation: 138196

The || operator doesn't catch exceptions, which is what happens when a required URL does not exist.

One way to make that work is to use a method or a computed prop that handles the require error, defaulting to day-1.jpg:

<template>
  <img :src="imgUrl">
</template>

<script>
export default {
  props: {
    project: Object
  },
  computed: {
    imgUrl() {
      try {
        return require(`@assets/${this.project?.image}`)
      } catch (e) {
        return require('@/assets/day-1.jpg')
      }
    }
  }
}
</script>

Upvotes: 4

Related Questions