react dropzone with react image file resizer doesn't work

Viewed 595

I'm working with react dropzone and react image file resizer to upload multiple resized images when image drops down.
React Dropzone works fine ( uploading, show thumbnail ) without react image file resizer.
But combining two modules together, when image drops down it gets resized well but somehow doesn't update state.
It seems to be caused by using async,await in wrong way,
because console.log in finally clause appear first than console.log in try - await clause.
Here is the code that has problem.

This is react image file resizer code :

  const resizeFile = (file) =>
    new Promise((resolve) => {
      Resizer.imageFileResizer(
        file,
        300,
        300,
        "JPEG",
        80,
        0,
        (uri) => {
          resolve(uri);
        },
        "file"
      );
    });

This is onDrop method in react dropzone :

/// onDrop method in react dropzone
  const onDrop = async (images) => {
    let uploadBranchImages = [];
    try {
      await images.map((image) => {
        resizeFile(image).then((resizedImage) => {
          console.log(resizedImage);
          Object.assign(resizedImage, {
            preview: URL.createObjectURL(resizedImage),
          });
          uploadBranchImages.push(resizedImage);
        });
      });
    } catch (err) {
      console.log(err);
    } finally {
      console.log(uploadBranchImages);
      let tempBranchImages = [...state.branchImages, ...uploadBranchImages];
      console.log(tempBranchImages);

      setState({
        ...state,
        branchImages: tempBranchImages,
      });
    }
  };

In this code, log of uploadBranch in finally clause first appears, and log of tempBranchImages comes next and log of resizedImage in try clause last.
Plus, resized image shows well when I put URL in chrome address bar.

Here is capture of logs : capture_of_logs

So the question is... why these codes don't work sequentially?
Because of this, images do not show in drop zone after uploads.

For more information, I'll attach logs without react image file resizer. It differs with above captures in preview of array

( [ ] vs [file] )

Here is the logs : capture_of_logs_without_resize

Any advice will be appreciated..

2 Answers

Thanks a lot for your answers, it was exactly what I was looking for. In case some want to use the hook useDropzone():

const {getRootProps, getInputProps, isDragActive, isDragAccept, isDragReject} = useDropzone({
        accept: "image/*",
        maxFiles: 1,
        onDrop: async (acceptedFiles: any) => {
            await Promise.all(
                acceptedFiles.map((image: any) => {
                    return resizeFile(image);
                })
            ).then((uploadBranchImages) => {
                console.log('Upload Branch Images', uploadBranchImages);
                setImages(
                    uploadBranchImages
                        .map((image: any) => {
                                const imageModified = Object.assign(image, {
                                    preview: URL.createObjectURL(image)
                                })

                                handleFireBaseUpload(imageModified);
                                return imageModified;
                            }
                        )
                );

            })
        }
    });

Found the answer ...
The problem came from promises with map.
Map didn't wait for previous promise,
so I used Promise.all() to wait all promises.
After resolving all promises, I updated states with its result
and it works well..
Hope someone gets informed by my case !

Here is the code...

  const resizeFile = (file) =>
    new Promise((resolve) => {
      Resizer.imageFileResizer(
        file,
        300,
        300,
        "JPEG",
        80,
        0,
        (image) => {
          Object.assign(image, {
            preview: URL.createObjectURL(image),
            path: image.name,
          });
          resolve(image);
        },
        "file"
      );
    });

  /**
   * dropdown 모듈을 사용한 이미지 업로드
   */
  const onDrop = async (images) => {
    await Promise.all(
      images.map((image) => {
        return resizeFile(image);
      })
    ).then((uploadBranchImages) => {
      let tempBranchImages = [...state.branchImages, ...uploadBranchImages];
      console.log(tempBranchImages);

      setState({
        ...state,
        branchImages: uploadBranchImages,
      });
    });
  };
Related