I’m trying to read the image dimensions in JS, but I face strange behaviours that I don’t understand. I have 3 Log-Console, and the one that I read the image properties is always executed after the contents are loaded (this is supposed to get executed the first), so practically I take always 0,0 of the dimensions in the first run.
var data_indexed = createDataSource(data_array);
console.log("third console - ", data_indexed)
function createDataSource(arr){
var data = [];
for (var j=1;j<arr.length;j++){
//start to value 1 to ignore the id
if (arr[j].search("static")==0){
var getDimensions = async (url) => {
const img = new Image();
img.src = url;
await img.decode();
return img;
};
var imgWidth1=0;
var imgHeight1=0;
getDimensions(arr[j]).then(img => {
imgHeight1 = img.naturalHeight
imgWidth1 = img.naturalWidth
console.log("first console - ",imgHeight1,imgWidth1);
});
console.log("second console - ",imgHeight1,imgWidth1);
data.push(
{
src: `${arr[j]}`,
width: imgWidth1,
height: imgHeight1,
alt: `image ${j}`,
},)
}
else if (arr[j].search("https://")==0){
var res = arr[j].split("=");
var vidEmbed = "https://www.youtube.com/embed/"+res[1];
data.push(
{
html: `<div class="ratio ratio-16x9 "><iframe src="${vidEmbed}" allowfullscreen></iframe></div>`
},
)
}
}
return data;
}
2
Answers
I have tried your code and get message on console like this
I’ve changed the code like this.
The main reason which makes you confusion is that async function and await.
As you’ve mentioned we could get image dimension after image is loaded.
This is called first than the code in then clause of getDimension() function since getDimension() is async function.
we could get image dimensions after calling await on getDimension() function.
Hope this would be helped!
The problem you are facing is that instead of waiting for the image to load, you continue to the second console.log, and
.then
executes afterwards. To fix this, you need to make your top level function async, soasync function createDataSource(url)
and then await the function, which will cause your code first to wait for the image to get loaded and decoded.This will now trigger the variable assignments and console.log only after the getDimensions function is finished running.
await
-ing a function is preferrable to using .then, since it makes the code much cleaner.And for the third console to run third, you need to await the createDataSource call too: you need to wrap the call and console log in an async function like so: