【问题标题】:Chaining Asynchronous Function Calls with Stripe and Axios in React在 React 中使用 Stripe 和 Axios 链接异步函数调用
【发布时间】:2019-06-04 00:58:09
【问题描述】:

所以我尝试提交用户输入其信用卡的订单。

为此,我调用 order 方法,该方法对 Stripe (createSource) 进行 API 调用以创建支付来源。然后我使用 axios 将订单参数发布到我的 Rails 后端,其中我发送刚刚创建的源的 id (source.id)。

async order() {
      let {source} = await this.props.stripe.createSource({type: 'card', currency: 'eur', owner: {email: this.props.currentUserEmail}});
      axios.post("/orders", {sourceId: source.id,
                              mealId: this.props.mealId,
                              price: this.state.mealPrice,

                              selectedPickupTime: this.state.selectedPickupTime
                            })
}

问题是,我认为当 axios 将 post 请求发送到后端时尚未创建源,因为我收到以下错误:

Unhandled Rejection (TypeError): Cannot read property 'id' of undefined for source.id

如何更改它并等待在 axios 发送发布请求之前创建源?

【问题讨论】:

    标签: javascript reactjs stripe-payments axios


    【解决方案1】:

    创建源时可能会出错。根据条带docs,您需要通过这种方式检查请求是否成功。

    async order() {
          // Either Source or Error
          let {source, error} = await this.props.stripe.createSource({type: 'card', currency: 'eur', owner: {email: this.props.currentUserEmail}});
    
          if (error) { // there was an error
            console.error('Unable to create a source due to', error) 
          } else {
            axios.post("/orders", {sourceId: source.id,
                                  mealId: this.props.mealId,
                                  price: this.state.mealPrice,
    
                                  selectedPickupTime: this.state.selectedPickupTime
                                })
         }
    }
    

    【讨论】:

    • 感谢您的帮助!好的,所以这是一个错误处理问题而不是异步问题?
    • @JulesCorb 对。根据文档,该方法返回一个始终得到解决的承诺。因此错误被编码为成功(源)或错误的返回值。
    【解决方案2】:

    docs 看来,正确的做法是:

    class CheckoutForm extends React.Component {
      handleSubmit = (ev) => {
        // We don't want to let default form submission happen here, which would refresh the page.
        ev.preventDefault();
        this.props.stripe.createSource({type: 'card', currency: 'eur', owner: {email: this.props.currentUserEmail}})
          .then(source => axios.post("/orders", {sourceId: source.id, mealId: this.props.mealId, price: this.state.mealPrice, selectedPickupTime: this.state.selectedPickupTime }))
          .catch(err => console.log(err));
    
      }
    };
    

    【讨论】:

    • 这似乎合乎逻辑,但 source.id 会被定义吗?因为我没有将 createSource 定义为 const {source}
    • 如果 Promise 已通过源解决,则可以通过将源传递给链中的以下 Promise 来使源可用,是的。
    【解决方案3】:

    在您的情况下,异步函数存在错误。为您的实现使用 try-catch 以处理 Promise 拒绝。

    async order() {
      try {
        let source = await this.props.stripe.createSource({ type: 'card', currency: 'eur', owner: { email: this.props.currentUserEmail }});
        axios.post("/orders", {
          sourceId: source.id,
          mealId: this.props.mealId,
          price: this.state.mealPrice,
          selectedPickupTime: this.state.selectedPickupTime
        });
      }
      catch (err) { // there was an error
        console.error('Unable to create a source due to', error)
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-05
      • 1970-01-01
      • 1970-01-01
      • 2021-02-21
      • 2017-08-13
      • 2019-06-05
      • 2020-08-01
      • 2020-06-11
      相关资源
      最近更新 更多