piotrruss
piotrruss

Reputation: 439

Javascript - can't iterate through array of objects with images

I have difficulties with iterating through array of objects which contains image. As my code below shows the array in console looks kind of empty but when I open it in console, I see all this objects also with iteration numbers. I can't google and get to the point how to transform it into proper working array to make for in loop and iterate through it in Vue.js. I attach you the code where comments says more than my description.

        const frameImage = [
        {
            url: 'http://www.realmadryt.pl/fotki/_up/newsy/lukamodric_165.png'
        },
        {
            url: 'http://www.realmadryt.pl/fotki/_up/newsy/florentinoperez_11.jpg'
        },
        {
            url: 'http://www.realmadryt.pl/fotki/_up/newsy/ramosbarkinsta1.jpg'
        },
        {
            url: 'http://www.realmadryt.pl/fotki/_up/newsy/lukamodric_165.png'
        },
        {
            url: 'http://www.realmadryt.pl/fotki/_up/newsy/florentinoperez_11.jpg'
        },
        {
            url: 'http://www.realmadryt.pl/fotki/_up/newsy/ramosbarkinsta1.jpg'
        },
    ];

    let createdImages = [];

    frameImage.forEach(item => {
        const image = new Image();
        image.src = item.url;
        image.onload = () => {
            // set image only when it is loaded
            createdImages.push({
                image,
                width: image.width,
                height: image.height,
                x: 0,
                y: 0,
                draggable: true
            });
        };
    });
    console.log(createdImages)


    // nothing happens
    createdImages.forEach(item => {
        console.log(item)
    });

    //also nothing happens
    for(img in createdImages) {
        console.log(img);
    }

    //length is actually 0?
    console.log(createdImages.length)

Also jsFiddle: LINK

Upvotes: 1

Views: 517

Answers (1)

Phil
Phil

Reputation: 164733

I would map the array of URLs to an array of promises that resolve with your object when the image has loaded. Then use Promise.all to wait for them all to load (resolve). For example

Promise.all(frameImage.map(({ url }) => new Promise((resolve, reject) => {
  const image = new Image()
  image.onload = () => resolve({
    image,
    width: image.width,
    height: image.height,
    x: 0,
    y: 0,
    draggable: true
  })
  image.onerror = reject
  image.src = src
}))).then(createdImages => {
  // now you can iterate
}).catch(err => {
  console.error('Could not load all images', err)
})

Upvotes: 1

Related Questions