【问题标题】:How do I loop through an array item of json and make async API requests with certain json objects如何循环遍历 json 的数组项并使用某些 json 对象发出异步 API 请求
【发布时间】:2021-02-10 08:26:32
【问题描述】:

如果我的问题看起来有点像新手,我深表歉意,我对异步编程很陌生,我仍在努力解决所有问题。我也试图弄清楚如何在这里提出好的问题,所以我试图包括正确的信息和一个可重复的例子。谢谢

我正在建立一个简单的在线商店,只有四种产品。

当我的服务器端客户端通过 JSON 接收用户购物车内容时,它接收 product_id、数量和 price_id 作为 JSON 数据数组

我正在尝试将其配置为

  1. 循环遍历每个数组项,

  2. 获取 product_id 和 price_id, 将它们发送到条带 API 以分别接收产品对象和价格对象,

  3. 将 price 对象中的“unit_amount”值和 products 对象中的“images”值和“name”值分配给它们自己的变量

  4. 将软管变量放入一个数组,并将该数组推送到 lineItems 数组,该数组将用作对 Stripe Checkout 的创建会话请求的变量

简而言之:

预期行为:从数组中的每个项目生成 price_data 对象,数组与 line_items 对象一起发送到会话请求以条带结帐,然后用户被重定向到结帐页面,结帐中包含 price_data 项目。

当前行为:从 Stripe api 检索的价格数据无法分配给变量或传递给 price_data。返回类型错误:无法读取未定义的属性“unit_amount”。

const stripe = require('stripe')('sk_test_51Hemg7ETi3TpMq6bUmiw1HoxERPmReLOT3YLthf11MEVh4xCmnsmxtFHZRlWpimoSnwHjmUOKNkOFsbr9lEEIybe00SQF71RtF');
//This is a test secret key for a dummy stripe account, don't worry I'm not sharing anything sensitive 
const express = require('express');
const app = express();
app.use(express.static('.'));
const YOUR_DOMAIN = 'http://localhost:4242';



app.post('/create-session', async(req, res) => {
      //Body of the POST request
      const cartContents = [{
          product_id: 'prod_IHb8dX3ESy2kwk',
          quantity: '2',
          price_id: 'price_1Hh1wcETi3TpMq6bSjVCf3EI'
        },
        {
          product_id: 'prod_IFIIyTO0fHCfGx',
          quantity: '2',
          price_id: 'price_1HeniJETi3TpMq6bPDWb3lrp'
        }
      ]

      //Array to push parsed data onto for line_items object in stripe session
      var lineItems = [];

      cartContents.forEach(async(item, index, array) => {
        //Retrieve price object from stripe API:
        const price = await stripe.prices.retrieve(
          item.price_id
        ).then(
          function(message) {
            console.log(message.unit_amount);
            //log the unit_amount value from price object
          },
          function(error) {
            console.log("Reject:", error);
          }
        );
        //retrieve product object from stripe API
        const product = await stripe.products.retrieve(

          item.product_id
        ).catch(err => console.error('error also'));

        console.log(product.name)

        // retrieve "name" and "images" from returned product object and assign to variable
        const productName = product.name;
        const productImage = product.images;
        //retrieve "unit_amount" from returned price object and assign to variable
        const productPrice = price.unit_amount

        //retrieve item quantity from cartContents object and assign to variable
        const productQuantity = item.quantity

        //Add variables to item and push to lineItems array
        lineItems.push({
          price_data: {
            currency: 'usd',
            product_data: {
              name: productName,
              images: [productImage],
            },
            unit_amount: productPrice,
          },
          quantity: productQuantity,
        })
      });
      const session = await stripe.checkout.sessions.create({
        payment_method_types: ['card'],
        line_items: lineItems,
        mode: 'payment',
        success_url: `http://localhost:5001/success.html`,
        cancel_url: `http://localhost:5001/cancel.html`,
      });
      res.json({
        id: session.id
      });

谢谢

【问题讨论】:

  • .forEach(async ... 总是闻起来像麻烦 - 在异步函数中使用 for...of 循环
  • 嗨,我很抱歉,但建议的问题对我没有任何意义。它的结构不同,问题中的示例与我当前的代码完全不匹配。能否请您再次打开问题?
  • 你的代码有.forEach(async ...问题中的代码有.forEach(async ...这就是问题所在,完全一样
  • 文件。它附加的是一个函数,而我的代码中的那个是json数据。内容也完全不同,这些差异对我来说没有任何意义。
  • 你还有其他问题...例如const price = await stripe.prices.retrieve( item.price_id ).then( function(message) { ... etc}) ....价格将是未定义的,因为 .then 返回未定义

标签: javascript node.js express stripe-payments


【解决方案1】:

您的主要问题是 .forEach(async 很少(如果有的话)像您期望的那样工作

但是,另一个问题是

const price = await stripe.prices.retrieve(item.price_id)
.then(function(message) {
    console.log(message.unit_amount);
    //log the unit_amount value from price object
  },
  function(error) {
    console.log("Reject:", error);
  }
);

这将导致price 成为undefined - 因为.then 不返回任何内容

.then/.catchasync/await 混合总是(通常)不是一个好主意

所以 - 解决这两个问题 - 你的代码变成了

const stripe = require('stripe')('sk_test_51Hemg7ETi3TpMq6bUmiw1HoxERPmReLOT3YLthf11MEVh4xCmnsmxtFHZRlWpimoSnwHjmUOKNkOFsbr9lEEIybe00SQF71RtF');
//This is a test secret key for a dummy stripe account, don't worry I'm not sharing anything sensitive
const express = require('express');
const app = express();
app.use(express.static('.'));
const YOUR_DOMAIN = 'http://localhost:4242';

app.post('/create-session', async(req, res) => {
    //Body of the POST request
    const cartContents = [{
            product_id: 'prod_IHb8dX3ESy2kwk',
            quantity: '2',
            price_id: 'price_1Hh1wcETi3TpMq6bSjVCf3EI'
        }, {
            product_id: 'prod_IFIIyTO0fHCfGx',
            quantity: '2',
            price_id: 'price_1HeniJETi3TpMq6bPDWb3lrp'
        }
    ];

    //Array to push parsed data onto for line_items object in stripe session
    const lineItems = [];
    try {
        for (let item of cartContents) {
            //Retrieve price object from stripe API:
            const price = await stripe.prices.retrieve(item.price_id);
            console.log(price.unit_amount);
            //log the unit_amount value from price object
            //retrieve product object from stripe API
            const product = await stripe.products.retrieve(item.product_id);
            console.log(product.name);
            // retrieve "name" and "images" from returned product object and assign to variable
            const productName = product.name;
            const productImage = product.images;
            //retrieve "unit_amount" from returned price object and assign to variable
            const productPrice = price.unit_amount;
            //retrieve item quantity from cartContents object and assign to variable
            const productQuantity = item.quantity;
            //Add variables to item and push to lineItems array
            lineItems.push({
                price_data: {
                    currency: 'usd',
                    product_data: {
                        name: productName,
                        images: [productImage],
                    },
                    unit_amount: productPrice,
                },
                quantity: productQuantity,
            });
        }
        const session = await stripe.checkout.sessions.create({
            payment_method_types: ['card'],
            line_items: lineItems,
            mode: 'payment',
            success_url: `http://localhost:5001/success.html`,
            cancel_url: `http://localhost:5001/cancel.html`,
        });
        res.json({id: session.id});
    } catch(e) {
        // handle error here
    }
});

【讨论】:

    猜你喜欢
    • 2023-03-07
    • 2016-07-28
    • 2019-12-17
    • 1970-01-01
    • 2015-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多