Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a forEach loop synchronous [duplicate]

I have an asynchronous problem here. The forEach is still running when res.json({ errors }); returns so all the errors aren't picked up. How do I deal with this?

router.post('/new/user', async function (req, res, next) {
    const validateEmail = async (email) => {
      var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
      return re.test(email);
    };
    
    const reqBody = { email, password };
    
    let errors = {};

    Object.keys(reqBody).forEach(async (field) => {
      if (field === 'email' && validateEmail(await reqBody[field])) {
        errors = { ...errors, [field]: 'Not a valid Email' };
      }
      console.log(3);
    
      if (field === 'password' && password !== '' && password < 4) {
        errors = { ...errors, [field]: 'Password too short' };
      }
    });
    
    if (Object.keys(errors).length > 0) {
      res.json({ errors });
    }
}
like image 316
bp123 Avatar asked Oct 27 '25 09:10

bp123


2 Answers

Use for...of to loop over the array elements instead and you can use await.

for(const field of Object.keys(reqBody)){
   //Code using await
}
like image 154
Unmitigated Avatar answered Oct 29 '25 22:10

Unmitigated


using map instead of forEach to get promises Object.keys(reqBody).map(async (field) => {...} and then using Promise. allSettled to wait for all promise resolved or rejected and you can catch that error to log

router.post('/new/user', async function (req, res, next) {
    const validateEmail = async (email) => {
      var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
      return re.test(email);
    };
    
    const reqBody = { email, password };
    
    try{
      const promises =  Object.keys(reqBody).map(async (field) => {
      if (field === 'email' && validateEmail(await reqBody[field])) {
        Promise.reject({[field]: 'Not a valid Email'})
      }
      console.log(3);
    
      if (field === 'password' && password !== '' && password < 4) {
        Promise.reject({[field]: 'Password too short'})
      }
     });
     // List of resolved and rejected promises
     const results = await Promise. allSettled(promises)
     const errors = results.filter(result => result.status === "rejected")
     if (Object.keys(results).length > 0) {
        res.json({ errors });
     }
    }catch(error){
      res.json({ error });
    }
}
like image 37
Tony Nguyen Avatar answered Oct 29 '25 22:10

Tony Nguyen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!