NealVDV
NealVDV

Reputation: 2532

Promise inside Array.map or loop alternative?

I was wondering how you would solve the following issue. I have an upload component which accepts multiple files. So onDrop gives me accepted and rejected files (based on extension and size).

From those accepted I need to figure out if they have the correct dimensions and I'm would like to use the browser-image-size package.

This package returns a promise, but as you can see below I need to check this for each file in the accepted argument provided. I tried the following but as you can see this always returns an emty array and undefined.

How do I solve this issue?

const checkDimensions = (file) => {
  return Promise.resolve(file);
}

const handleFiles = (accepted, rejected) => {
  const acceptedFiles = [];
  const errors = [];

  accepted.map(file =>
    checkDimensions(file)
    .catch((error) => errors.push(error))
    .then((file) => acceptedFiles.push(file))
  );

  // both log empty array
  console.log(acceptedFiles);
  console.log(errors);
}

// Logs undefined 
console.log(handleFiles(['test file']))

Upvotes: 0

Views: 90

Answers (1)

Laoujin
Laoujin

Reputation: 10229

Your console logs are executed before the checkDimensions had a chance to complete it's work.

const handleFiles = (accepted, rejected) => {
  const acceptedFiles = [];
  const errors = [];

  accepted.map(file => checkDimensions(file)
    .then(file => acceptedFiles.push(file), error => errors.push(error))
    .then(() => {
      console.log(acceptedFiles);
      console.log(errors);
    });
  );
}

A then has an optional second parameter. The difference between catch followed by then versus then with 2 arguments is subtle: If checkDimensions decides to reject a file, the acceptedFiles.push(file) will still be executed.

Upvotes: 1

Related Questions