Stripe和MogoDB集成的GraphQL突变过早地返回null

时间:2017-09-21 13:07:27

标签: javascript mongodb stripe-payments graphql

我试图在GraphQL中创建一个使用Stripe向用户收费但我无法让用户返回客户端的突变。一切都在我的数据库中运行良好,付款已完成,但在我的客户端,.then()过早地触发null结果,而它应该返回我编辑的用户。它实际上是在stripe.charges在我的服务器上完成之前触发的。

服务器端:



chargeUser(args) {
    const { userId, membershipId, stripeToken } = args;

    return User.findById(userId)
        .then((user) => {
            return Membership.findById(membershipId)
                .then((membership) => {
                    return stripe.charges.create({
                        amount: membership.price * 100,
                        currency: 'chf',
                        source: stripeToken,
                        description: `${user.firstname} ${user.lastname}`
                    }, function(err) {
                        if (!err) {
                            user.membership = membershipId;
                            return user.save();
                        } else {
                            console.log(err)
                        }
                    });
                })
        });
}




客户方:



this.props.mutate({
    variables: {
        membershipId: this.props.membershipId,
        userId: global.userId,
        stripeToken: token.tokenId
    }
})
.then((res) => {
    // Returning null before the stripe.charges has finished
    console.log(res)
})




1 个答案:

答案 0 :(得分:1)

这里的问题是stripe.charges.create()使用回调;它不会回报承诺。与promise不同,在回调中返回用户不会做任何事情 - 您的promise链终止于stripe.charges.create()的返回值,该值为null。

为了让你的解析器等待回调,你必须将它包装在一个承诺中,如下所示:

return User.findById(userId)
  .then((user) => {
    return Membership.findById(membershipId)
      .then((membership) => {
        return new Promise((resolve, reject) => {
          stripe.charges.create({
            amount: membership.price * 100,
            currency: 'chf',
            source: stripeToken,
            description: `${user.firstname} ${user.lastname}`
          }, (err) => {
            err ? reject(err) : resolve()
          })
        })
      })
      .then(() => user.save())
  })

或者,用async / await清理一下:

const chargeUser = async (args) => {
    const { userId, membershipId, stripeToken } = args;

    const user = await User.findById(userId)
    const membership = await Membership.findById(membershipId)
    await new Promise((resolve, reject) => {
      stripe.charges.create({
        amount: membership.price * 100,
        currency: 'chf',
        source: stripeToken,
        description: `${user.firstname} ${user.lastname}`
      }, (err) => {
        err ? reject(err) : resolve()
      })
    })
    return user.save()
}