简体   繁体   中英

Async function inside .map throws error after first array object

I am trying to loop through an array to charge a payment to each array object. The function works for the first array object. I am able to see the charge on the stripe side so. The stripe block of code has been tested separately and works without issue.

router.post('/test', async (req, res) =>{
  try {
    const newItem = req.body.results;
    return auctions = newItem
        .map(x =>({
          auction_id: x._id.$oid,
          status: x.status,
          bid: x.bidHistory.bid.$numberInt,
          name: x.bidHistory.name,
          user_id: x.bidHistory.user
        }))
        .map(async (y) =>{
          //Perform charge here
          try {
            //Get stripe_id
            const user = await User.findOne({uid: y.user_id})
              if (!user.stripe_id) throw Error("User doesn't have a stripe id");
             
            const paymentIntent = await stripe.paymentIntents.create({
              amount: y.bid,
              currency: 'usd',
              customer: (user.stripe_id),
              payment_method: (user.stripe_cc),
              off_session: true,
              confirm: true,
            });
    
            res.status(200).json(paymentIntent);
    
          } catch (err) {
            // Error code will be authentication_required if authentication is needed
            console.log('Error code is: ', err.code);        
            const paymentIntentRetrieved = await stripe.paymentIntents.retrieve(err.raw.payment_intent.id);
            console.log('PI retrieved: ', paymentIntentRetrieved.id);
    
            res.status(400).json(paymentIntentRetrieved.id);
          }  
           
        })      
  } catch (err) {        
    res.status(400).json(err);
  }  
})

When trying to loop to the second object in the array, I get an error:

"Error code is:  undefined
[0] (node:44590) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'payment_intent' of undefined
[0]     at /Users/Alex/Documents/Webdev/mern-nowaitlist/routes/api/stripe.js:151:89"

Which is odd because it worked for the first array object. Any clue what's going on here? Do I need to wait before sending another request to stripe?

EDIT 1: I added a promise.all. The loop worked only for the 1st time again. I commented out all the stripe stuff to see what was going on.

router.post('/test', async (req, res) =>{
  try {
    const newItem = req.body.results;
    const auctions = newItem
        .map(x =>({
          auction_id: x._id.$oid,
          status: x.status,
          bid: x.bidHistory.bid.$numberInt,
          name: x.bidHistory.name,
          user_id: x.bidHistory.user
        }))
    const results = Promise.all(auctions    
        .map((y) =>{
          //Perform charge here
          
          try {        
            y.bid= y.bid+1;
            res.status(200).json(y.bid)
          } catch (err) {
            res.status(400).json(err);
            console.log(err)
          }  
           
        }) 
        )  
       return results    
  } catch (err) {        
    res.status(400).json(err);
  }  
})

I now get the following error when trying to run the code:

UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

I'm not sure what you expect err.raw to be, but it appears that err.raw.payment_intent is undefined, throwing a new error within your catch block.

Try removing the payment intent retrieval and just log the error to see what is failing in the first place, then fix that.

The callback you passed to Array.map() returns Promise, so you need to await for it to be resolved by Promise.all. Or loop with a for statement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM