问题描述
我正在尝试在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,因此您应该很聪明。