Vue.js/Nuxt.js Load Fallback Image on 404 - javascript

I am trying to set a default image (placeholder image) in case the image resource is not found (404). I have a dict article which has a value for the key author_image. So that string is not empty but it just can't load that image.
In my template:
<img
:src="article.author_image"
alt="Author Image"
#error="setFallbackImageUrl"
>
In my methods:
methods: {
setFallbackImageUrl(event) {
console.log('Image failed to load, setting fallback.')
event.target.src = '~/assets/icons/avatar.svg'
}
}
I can see in my console log that setFallbackImageUrl is called but the image src is not updated. I made sure that the avatar.svg is actually correct, if I just hard code that over article.author_image that works.
Any suggestions on what I might be doing wrong?

The issue comes while loading your image via vue loader and webpack as the file extensions (.png, .svg, etc) are not module requests (read more about handling assets with vue loader).
You'll need to wrap it in the require to access it. the example by #Toni Michel Caubet works because he is using a link.
This Works for me.
methods: {
setFallbackImageUrl(event) {
console.log('Image failed to load, setting fallback.')
event.target.src = require(`~/assets/icons/${'avatar' + '.svg'}`)
}
}
Note: it's not needed to wrap the image in "${'avatar' + '.svg'}" i just removed my dynamic values and added "avatar".

Just in case someone is hitting a brick wall with webpack (files from assets/static)
The accepted answer from here should resolve it:
Dynamic img src URL with "OR" statement not working properly in NUXT component

Related

Why won't item utilize texture I made?

(Using IntelliJ to code everything)
I'm making a Minecraft Mod and when I go to test my custom item out the name works perfectly with spaces and all, but for some odd reason it won't use the texture, instead when loading the texture it gives the error:
"Unable to load model: 'bullets:really_long_item_name_here#inventory' referenced from: bullets:really_long_item_name_here#inventory: java.io.FileNotFoundException: bullets:models/item/really_long_item_name_here.json"
The image for the texture is a .png file and has the correct name.
Heres the code within the models/item directory
{
"parent": "item/generated",
"textures": {
"layer0": "bullets:items/really_long_item_name_here"
}
}
I'm pretty sure it's because you put this json in a wrong location. As your stacktrace says: java.io.FileNotFoundException: bullets:models/item/really_long_item_name_here.json means it can't find your model, which have to be in resources/assets/<modid>/models/item. Then, if your texture has a proper location (resources/assets/<modid>/textures/items/really_long_item_name_here.png) it should work.
For IntelliJ users
In the project tree IntelliJ shows subfolder as folderA.folderB instead of folderA/folderB.
It took me half an hour to realize that I created a folder called assets.examplemodid instead of folder examplemodid inside assets.

ngx-translate .instant() doesn't load is not instant

I translate data that I get locally, they are not async data.
My native text comes from an enum imported in my file V2VehiculeOutput.StatusEnum
But I am forced to reload the page if I want to see the translation.
I tried to load translations, with the code bellow, from the ngOnInit and the constructor but it doesn't change anything.
Object.keys(V2VehiculeOutput.StatusEnum).forEach(s => {
console.log(this.translate.instant('FILTERS.VEHICULE.STATUS.' + V2VehiculeOutput.StatusEnum[s]));
});
});
I read that issue https://github.com/ngx-translate/core/issues/517 but my data is not even async ... So why translate.instant is not loading my data directly ?
Am I missing something ?
This post https://www.digitalocean.com/community/tutorials/angular-ngx-translate helped me.
It seems to work normally now using this exemple.
this.translate.get(['login.username', 'login.password'])
.subscribe(translations => {
this.usernameLabel = translations['login.username'];
this.passwordLabel = translations['login.password'];
});
The bug was not on each load so I will keep an eye on that but it feels good for the moment.

Image onload not being called in vue

I am trying to build a Vue App and I am new to Vue, I am trying to load an image at runtime in Js/Ts with the code below
console.log("code is being called");
let image = new Image();
image.onload = (event) => {
console.log("image loaded");
}
image.src = "static/prison_tileset.png";
The code works fine on a regular html file, in Vue however, the onload method isn't being called. The first console.log is being called. I am sure that the image is found because if I manipulate the path to something wrong on purpose I get an error that the file isn't being found. It's just that the onload event isn't being firied.
I'd be very happy if somebody could help me with that!
I've gotten it to work now! I will answer the question myself as best as I can. To use local assets in view you have to load them via Webpack like this:
const Logo = require("../assets/logo.png");
this.image.src = Logo;
If you also happen to use electron you have to set the webSecurity in your entry file to false for electron to be allowed to access local files.

Dynamically loading assets with require() that might not exist in webpack + VueJS

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.

Meteor-Files thumbnail link

I am following this tutorial, https://github.com/VeliovGroup/Meteor-Files/wiki/Image-Processing
I am successful on creating thumbnails.
I am successful on adding versions in the collection.
I want to display the thumbnail. My problem now is how can I get link for <img> tag?
For the original image, I used FilesCollection.link(fileRef).
How can I do it same in thumbnails?
I am using Veliov meteor-files package and GraphicMagick.
I had the same issue, I think. Just to verify, there is a code snippet in the thumbnail generation that looks like this:
const upd = { $set: {} };
upd['$set']['versions.thumbnail'] = fileRef.versions.thumbnail;
This means that in the fileObj for the main file, there is a property named "versions" which now has a sub-property named "thumbnail".
Reading through the code, I find that you can access this from the main fileObj thus:
fileObj.link('thumbnail')
I have verified that this works. If you add other versions, I'm sure they work the same way.

Categories

Resources