Amine
Amine

Reputation: 2434

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.

Upvotes: 0

Views: 921

Answers (2)

Ayush Chaurasia
Ayush Chaurasia

Reputation: 1

If you want to get value of a promise,then you can use async await. or if you are using react then you can use usestate hook inside promise to get the value. Let see with the help of example :-

let suppose we have written fetch api in another file

export const GetAccess= async(data)=>{
    const dta=JSON.stringify(data)
    const tknurl="http://127.0.0.1:8000/api/token/refresh/";
    let resf=await fetch(tknurl,{
        method:"post",
        headers: {
            'Content-type': 'application/json',
          },
          body:dta
        });
        let resp=await resf.json();
        let accesstoken=resp.access;
        return accesstoken;

}

Then we can get it's response by using another async await in app.js file

const Cart = () => {
    const data=useSelector((state)=>{
        return state.users
    });
    const [order,setOrder]=useState([])
    const [msg,setMsg]=useState('');
    const navigate=useNavigate();
    const all=async()=>{
        let url="http://127.0.0.1:8000/addorder/"
        let access=await GetAccess(data);
        let resp=await fetch(url,{
            method:"get",
            headers:{
                'Authorization':'Bearer '+ String(access),
            }
        });
        let res=await resp.json();
        setOrder(res);

    }

If you have any doubt comment it below.

Upvotes: 0

Eliya Cohen
Eliya Cohen

Reputation: 11458

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.

Upvotes: 3

Related Questions