0

I want to .map instead of for loop but I still confuse how to use it here is my data

const arr =  [
  {
    name: "John",
    subject : [
      {
        subject_id : 1,
        score :20
      }
    ]
  },
  {
    name: "Doe",
     subject : [
      {
        subject_id : 2,
        score :20
      }
    ]
  }
]

I want to add subject detail into subject array

async getData() {
  for (let i in arr) {
    let data = arr[i];
    for (let i in data.subject) {
        const subject = data.subject[i];
        //this line code will get subject detail
        const getSubject = await this.getSubject(subject);
        subject["subjectData"] = getSubject;
    }
  }
}

everything work fine but How can I use map instead of for loop

example for output

{
  name: "Doe",
   subject : [
    {
      subject_id : 2,
      score :20,
      subjectData: {
        //some detail
      }
    }
  ]
}

Here is what I want to do

const newData = arr.map(async data => {
    const getSubject = data.subject;
    const subject = getSubject.map(async zp02 => {
      const getSubject = await this.getSubject(subject);
        return { getSubject };
    });
    return { ...data, subject };
});

my subject always return null .

the reason that I want to use map because I've read many people say It faster than for loop

  • Is their anyway to use map instead of for
  • I'm learning about clean code can you give me an Idea how to refactor code in nested for loop
Ach
  • 145
  • 1
  • 8
  • 2
    It's just not possible. If you want to use `map` with `await` the usual answer is to change your code to use `for` or `while` but since you are already using `for` and you don't want to use `for` the answer is you cannot change your code and it is impossible to get what you want. (Note: there are times when you want to use `map` instead of `for` - when you want to perform multiple parallel operations. Then you cannot `await` inside the `map` but instead `await` the return value of `map` in a `Promise.all()`) – slebetman Feb 24 '20 at 10:57
  • 1
    https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop/37576787#37576787 – Teemu Feb 24 '20 at 10:58

1 Answers1

3

Check this up https://dev.to/jhalvorson/how-do-i-use-async-await-with-array-map-1h3f.

From this article:

You can't async/await Array.map since synchronous code won't sit and wait for your asynchronous code to resolve, instead it will the fire the function and move on. This is desired behaviour as we don't want our Array.map to block the thread otherwise nothing would run whilst Array.map goes and does its thing. Knowing that is cool, however, it doesn't really help us if we need to await our Array.map().

Thankfully there is a solution, we can achieve what we want by utilising Promise.all

//For example, the following won't work:
const postIds = ['123', 'dn28e29', 'dn22je3'];

const posts = await postIds.map(id => {
return axios
 .get(`https://example.com/post/${id}`)
 .then(res => res.data)
 .catch(e => console.error(e));
}

console.log(posts) // [] it returns the promise, not the results 

//But this will:
const postIds = ['123', 'dn28e29', 'dn22je3'];

const posts = posts.map(post => {
  return axios
    .get(`https://example.com/post/${post.id}`)
    .then(res => res.data)
    .catch(e => console.error(e));
}

Promise.all(posts).then(res => console.log(`We have posts: ${res}!`));

Instead of immediately returning the Array.map we're assigning it to a variable and passing that variable to Promise.all, once that resolves we then have access to the new array returned by Array.map.

Kgn
  • 66
  • 3
  • well you can do this also by applying nested .then () once you get the response object assign that response object to another variable and you'll be able to access it. – Juhil Somaiya Feb 24 '20 at 11:07