I'm trying to load images dynamically which may or may not exist.
In this case, crypto-currency icons using their 3 letter symbol. I have a few hundred in .svg format in my statics library and when I pull data from a price server I try to match up the icons I have with the symbols coming from the server and to serve a fallback image if I don't have the asset.
In my index.vue I can get away with this code and everything works fine:
<img :src="'statics/icons/svg/' + coin.symbol + '.svg'" v-img-fallback="'statics/icons/svg/fallback.svg'"/>
However in a subcomponent that opens if a user clicks a coin the same code will fail to load both the primary and fallback images. I've tried numerous ways but the only way to get an image to load from my subcomponent is to either hard code it like this:
<img src="statics/icons/svg/btc.svg"/>
Which is impossible for me as I need the modal to be dynamically generated for any possible coin...
Or using require() like this:
<img :src="imageSrc" v-img-fallback="require('../statics/icons/svg/fallback.svg')"/>
// Computed:
imageSrc () {
if (this.coinData.symbol) {
return require('../statics/icons/svg/' + this.coinData.symbol + '.svg')
}
}
However this crashes my app if require()
looks for an asset that doesn't exist. I need a method that fails gracefully so that the v-img-fallback
can detect it and supply the fallback.
I've tried doing something like return require(image1) || require(fallback)
but it doesn't work.
This is a common request and latest WebPack, AFAIK (and I just searched for it again), does not expose an API for especifically testing the existence of a module.
In other words, you'd have to handle the uncertainty of the loading yourself. Example:
computed: {
imageSrc () {
if (this.coinData.symbol) {
try {
return require('../statics/icons/svg/' + this.coinData.symbol + '.svg')
} catch (e) {
if (e.name !== "ModuleNotFoundError") throw e; // handle false-positives
// in cordova, use the line below instead of the above
// if (!e.message.startsWith('Cannot find module')) throw e;
return require('../statics/icons/svg/fallback.svg');
}
}
return require('../statics/icons/svg/fallback.svg');
}
}
This way I'd argue you wouldn't even need a fallback src
in the template. You could return it in the computed property itself.
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