I am working on a react file-upload component. I got stuck with a rather trivial issue – I want for each file to show icon corresponding to a file extension. Icons are loaded via css as background images (using inline styles). The problem arises when I don't have an icon for given extension and thus want to show a fallback icon.
– I tried to use multiple css background-image declarations like this:
style={{
backgroundImage: `url(./icons/fallback.svg), url(./icons/${item.extension}.svg)`,
}}
or like this:
style={{
backgroundImage: `url(./icons/fallback.svg)`,
backgroundImage: `url(./icons/${item.extension}.svg)`,
}}
But it doesn't work, the fallback icon is not being used (or in one case I am not able to reproduce, both icon are shown, which is also undesired).
I tried to fetch
the file to determine if it does exist, but the node server (i use create-react-app) is configured in a way that returns 200 or 304 even if the file isn't actually present.
I tried to use a solution which creates an image and uses onload
and onerror
events as beeng suggested in this question, which actually works fine – i am currently using slightly modified implementation of image-exists npm module – but I wasn't able to figure out how to refactor this function to simply return a boolean. Using console.log()
and callbacks works fine; returning a boolean results in undefined
. I suppose it is due to an asynchronous behaviour od Image methods, but I wasn't able to create a workaround – maybe using a Promise API?
My code:
exists = src => {
const checks = {};
return callback => {
if (src in checks) {
return callback(checks[src]);
}
let img = new Image();
img.onload = function() {
checks[src] = true;
callback(true);
};
img.onerror = function() {
checks[src] = false;
callback(false);
};
img.src = src;
};
};
Render method:
render() {
// So far so good, logs as expected, but not such useful
console.log(this.exists('./icons/jpg.svg')(bool => {
if(bool) {
console.log('yes')
} else {
console.log('no');
}
}));
// ...
}
If I try to return a boolean directly, it results in undefined:
render() {
console.log(this.exists('./icons/jpg.svg')(bool => bool));
// ...
}