Search code examples
javascriptreactjspromise

How to get values from Promise in React?


I'm trying to create an array of objects from another array in React.

Here is my function

let filesArray = [];
filesArray = selectedDocuments.map(async (file) => {
  const imageStr = await toBase64(file);

  const parsed = imageStr.match(/^(data.*,)?(.*)$/);
  const type = parsed[1];
  const blob = parsed[2];

  return {
    content: blob,
    label: file.name,
    labelOriginal: file.name,
    dataType: type,
  }
})

selectedDocuments is the array of selected files toBase64 is a function I created that returns a Promise

The problem is that when I console filesArray I get this output

enter image description here

How can I extract the PromiseResult, and could someone explains to me what's happening and thank you.


Solution

  • What you want to do, is to wait for all nested promises to resolve. What you're actually doing, is mapping each file to an asynchronous (promise) value. In order to get the filesArray returned values, you can simply do:

    let filesArray = [];
    filesArray = Promise.all(selectedDocuments.map(async (file) => {
      const imageStr = await toBase64(file);
    
      const parsed = imageStr.match(/^(data.*,)?(.*)$/);
      const type = parsed[1];
      const blob = parsed[2];
    
      return {
        content: blob,
        label: file.name,
        labelOriginal: file.name,
        dataType: type,
      }
    }))
    

    A different way to write it inside for...of:

    let filesArray = [];
    
    for (const document of selectedDocuments) {
      const imageStr = await toBase64(file);
    
      const parsed = imageStr.match(/^(data.*,)?(.*)$/);
      const type = parsed[1];
      const blob = parsed[2];
    
      filesArray.push({
        content: blob,
        label: file.name,
        labelOriginal: file.name,
        dataType: type,
      })
    }
    

    The reason I used Promise.all in the first example and not in the second example, is because .map and for iterate differently.

    when you .map a value, you just run a callback with a return value. When you use the for loop, you iterate over it in the same scope, so each line will be executed one after the other.