1

我试图让 Stripe 在 Rails 环境中使用 Stimulus 控制器工作。当我按照 Stripe 说明使用 Checkout 时,它可以完美运行。当我使用刺激时(我认为!)是相同的代码,我在控制台中收到以下错误:

Error: TypeError: Cannot read property 'stripe' of undefined
at payment_controller.js:28

这似乎是以下代码行:

return this.stripe.redirectToCheckout({ sessionId: session.id });

以下是刺激代码的完整列表:

import { Controller } from "stimulus"

export default class extends Controller {

    connect() {
        console.log("I am loaded")
        let stripeMeta = document.querySelector('meta[name="stripe-key"]')
        if (stripeMeta === null) { return }

        let stripeKey = stripeMeta.getAttribute("content")
        this.stripe = Stripe(stripeKey)
        this.csrf = document.querySelector("meta[name='csrf-token']").getAttribute("content");
    }

    loadstripe() {
        fetch('/create-checkout-session', {
            method: 'POST',
            headers: {
                'X-CSRF-Token': this.csrf,
            },
        })
        .then(function(response) {
            return response.json();
        })
        .then(function(session) {
            console.log(session.id)
            console.log(this.stripe)
            return this.stripe.redirectToCheckout({ sessionId: session.id });
        })
        .then(function(result) {
            // If `redirectToCheckout` fails due to a browser or network
            // error, you should display the localized error message to your
            // customer using `error.message`.
            if (result.error) {
                alert(result.error.message);
            }
        })
        .catch(function(error) {
            console.error('Error:', error);
        });
    }
}

这似乎与以下内容相同:

    <script type="text/javascript">
    // Create an instance of the Stripe object with your publishable API key
    var stripeKey = document.querySelector('meta[name="stripe-key"]').getAttribute("content")
    var stripe = Stripe(stripeKey);
    var checkoutButton = document.getElementById('checkout-button');

    checkoutButton.addEventListener('click', function() {
        // Create a new Checkout Session using the server-side endpoint you
        // created in step 3.
        fetch('/create-checkout-session', {
            method: 'POST',
            headers: {
                'X-CSRF-Token': document.querySelector("meta[name='csrf-token']").getAttribute("content"),
            },
        })
            .then(function(response) {
                return response.json();
            })
            .then(function(session) {
                return stripe.redirectToCheckout({ sessionId: session.id });
            })
            .then(function(result) {
                // If `redirectToCheckout` fails due to a browser or network
                // error, you should display the localized error message to your
                // customer using `error.message`.
                if (result.error) {
                    alert(result.error.message);
                }
            })
            .catch(function(error) {
                console.error('Error:', error);
            });
    });
</script>

这是来自 Rails 的代码(似乎正在工作):

  def create_checkout_session
    session = Stripe::Checkout::Session.create(
      payment_method_types: ['card'],
      line_items: [{
        price_data: {
          currency: 'aud',
          product_data: {
            name: 'Hamper',
          },
          unit_amount: 10000,
        },
        quantity: 1,
      }],
      mode: 'payment',
      success_url: "https://localhost:5000/payment_success.html",
      cancel_url: "https://localhost:5000/payment_failed.html",
    )
    render json: { id: session.id }
  end

提前感谢您的帮助

4

1 回答 1

0

非常感谢 Stimulus Discourse 上的某个人提供了以下建议:

这看起来是 JS 的范围问题,而不是特定于 Stimulus。错误告诉您这this是未定义的,这是因为该代码正在一个回调函数中执行,该函数会更改范围 - 它不再在 Stimulus 控制器的范围内执行。

一个非常简单的解决方法是像这样更新 loadStripe:

loadStripe() {
  const stripe = this.stripe
  // ... etc.
}

并更新您的函数以访问该本地 const 而不是 this。您的函数将能够访问本地 const 并且您应该是金子。

于 2020-09-22T05:42:22.273 回答