Solution 1 :

      image.src = image;

This can’t work! And since you don’t have a reject in the inner promise, you don’t hear about this error. In the single-image example you use $image to distinguish the two images.

Just rename one of your two image variables.

loadImages(images) {
  return images.map(imageFile => {
    return new Promise(resolve => {
      const image = new Image();

      image.onload = () => {
        this.loadedImages.tile = image; //this.loadedImages is an instance variable
        resolve(image);
      };

      image.src = imageFile;
    });
  });
}

Solution 2 :

You don’t have a reject() function. You should have one to debug such errors.

Also, you use two different variables with the same name (image) on the same scope.

You are requiring a single image file, and as such you absolutely doesn’t need to create an array or much less an array of Promises.

Finally, consider using async/await syntax. It’s clearer, easier to debug and to understand, and its syntax is React-compatible.

Problem :

I am building a small game in HTML canvas in React. For that, I need to pre-load all the images before I start interacting with the canvas API. I am loading all of the images using Promise.all like follows:

import tile from '../assets/images/tile.png';
componentDidMount() {
  this.load();
 }

loadImages(images) {
  return images.map(image => {
    return new Promise(resolve => {
      const image = new Image();

      image.onload = () => {
        this.loadedImages.tile = image; //this.loadedImages is an instance variable
        resolve(image);
      };

      image.src = image;
    });
  });
}

load() {
  Promise.all(this.loadImages([tile]))
    .then(a => console.log(a))
    .catch(e => console.log(e));
 }

All of the images exist in the source directory of the project. I am not sure if Promises are used to load them since they are not fetched from web. Anyways, Promise.all in load method does not resolve all the promises so it does not print any of the logs in thenables/catch. However, I can able to resolve a single promise like follows:

 loadImage($image) {
  return new Promise(resolve => {
    const image = new Image();

    image.onload = () => {
      this.loadedImages.tile = image;
      resolve(image);
    };

    image.src = $image;
  });
}

load() {
  this.loadImage(tile)
    .then(a => console.log(a)) //prints the image element - a
    .catch(e => console.log(e));
 }

Please someone help me with this. Thank you!

Comments

Comment posted by Christian Fritz

I suspect you have an error with loading one of the images, but since the promise you create in the iteration doesn’t implement reject it fails silently. I would add a reject to the promise and see whether that will tell you anything more.

Comment posted by user117829

right, but the single promise resolution works so I assumed it wont reject. @ChristianFritz

Comment posted by user117829

@ChristianFritz Is promises an acceptable way to load images from relative path?

Comment posted by Christian Fritz

I think so, yes. Loading files and managing asynchronicity (promise or callbacks) are two pretty different tasks. They are pretty independent of one another.

By