条带和激励给出“无法读取未定义的属性”条”

问题描述

我正在尝试在Rails环境中使用Stimulus控制器使Stripe正常工作。当我按照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',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

在此先感谢您的帮助

解决方法

非常感谢刺激话语中的某人提供了以下建议:

这似乎是JS的范围界定问题,并非特定于Stimulus。该错误告诉您this是未定义的,这是因为该代码正在更改范围的回调函数中执行-不再在Stimulus控制器的范围内执行。

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

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

并更新您的函数以访问该本地const而不是此。您的函数将能够访问本地const,因此您应该很聪明。