1

Rails 環境で Stimulus コントローラーを使用して Stripe を動作させようとしています。Checkout を使用するための Stripe の指示に従うと、完全に機能します。(私が思うに!) 同じコードで刺激を使用している場合、コンソールに次のエラーが表示されます。

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の誰かが次のアドバイスを提供してくれたことに本当に感謝しています。

これは Stimulus に固有のものではなく、JS のスコーピングの問題のようです。エラーは、それthisが未定義であることを示しています。これは、コードがスコープを変更するコールバック関数で実行されているためです。これは、Stimulus コントローラーのスコープ内で実行されていません。

非常に簡単な修正は、次のように loadStripe を更新することです。

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

そして、これではなくそのローカル const にアクセスするように関数を更新します。関数はローカル const にアクセスできるようになり、ゴールデンになるはずです。

于 2020-09-22T05:42:22.273 に答える