質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Stripe

Stripeとは、米国のオンライン決済システム提供企業、及び同社が提供する決裁システムを指します。Webサイトやモバイルアプリにコードを組み込むことでクレジットカードなどの決済サービスが簡潔に追加できます。

Q&A

解決済

1回答

15926閲覧

Vueの子コンポーネントで「Uncaught (in promise) TypeError: Cannot read properties of undefined」

mikeko0901

総合スコア227

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Stripe

Stripeとは、米国のオンライン決済システム提供企業、及び同社が提供する決裁システムを指します。Webサイトやモバイルアプリにコードを組み込むことでクレジットカードなどの決済サービスが簡潔に追加できます。

0グッド

0クリップ

投稿2021/09/25 07:59

Vue.jsでStripeを用いて決済処理を実装しています。
(今回の質問には関係ないかと思いますが、サーバー側はLaravel8系)

Stripeのフォームをモーダルで表示させるところまではうまく行きましたが、
そこから先、axiosをやる前でエラーが出てしまいます。
イメージ説明
order_checkの「クレジットカード」をクリックすると↓
イメージ説明
クレジットカード入力フォームが出て(Stripe.jsで実装)、お支払をクリックでaxios送信したいのですが、その前でエラーが出ます。

以下、コードです。

■ShopOrderCheck.vue (order_checkページのVueコンポーネント。)
Stripeフォーム用コンポーネントの親コンポーネント

<template> <div> <main class="page-form"> <div class="bg-secondary-lighten-1 py-10"> <div class="container"> <div class="grouping shadow-md mb-6 md:w-10/12 max-w-screen-sm mx-auto"> <div class="flex items-center"> <div class="w-7/12"> <h3 class="font-bold text-lg">{{ product.name }}</h3> </div> </div> <form class="form form--check" action="../epsilon/order_ep.php" method="POST" id="order_form"> <div class="form__group"> <label class="form__label">メールアドレス</label> <div> <div>{{ request.buy_email }}<p style="color:#D31004;" class="text-sm">※正しいメールアドレスかをご確認ください。</p></div> </div> </div> <div class="form__group"> <label class="form__label">名前</label> <div> <div>{{ request.buy_name }}<p style="color:#D31004;" class="text-sm">※ご入力いただいたお名前で領収書を発行いたします。</p></div> </div> </div> <div class="form__group"> <label class="form__label">名前フリガナ</label> <div> <div>{{ request.buy_namekana }}</div> </div> </div> </form> <div class="mt-8" v-if="request.payment_method == 1"> <button type="button" class="form__button w-full button " id="order_card" @click="show">クレジットカード</button> </div> <div class="mt-8" v-else> <button type="button" class="form__button w-full button" id="order_bank">銀行振込</button> </div> </div> </div> </div> </main> <stripe-card :product="product" :request="request" :public_key="send_public_key" :csrf = "csrf" ></stripe-card> </div> </template> <script> export default { props: { csrf: { type: String, }, product: { type: Object, }, request: { type: Object }, public_key: { type: Object, } }, data() { return { errors: [], send_public_key: this.public_key.value, } }, mounted() { console.log(this.public_key.value); }, computed: { getPaymentMethod: function() { if(this.request.payment_method == 1) { return "クレジットカード"; } else { return "銀行振込"; } }, }, methods: { show : function() { this.$modal.show('stripe-card'); }, hide : function () { this.$modal.hide('stripe-card'); }, regist: function() { }, }, } </script>

■問題のStripe用クレジットカードフォームの子コンポーネント StripeCard.vue

<template> <modal name="stripe-card" @opened="setupStripe"> <div> <input type="hidden" name="_token" v-bind:value="this.csrf"> <label for="exampleInputEmail1">カード名義</label> <input type="test" class="form-control col-sm-5" id="card-holder-name" required v-model="Form.cardHolderName"> <label for="exampleInputPassword1">カード番号</label> <div class="form-group MyCardElement col-sm-5" id="card-element"></div> <div id="card-errors" role="alert" style='color:red'></div> <button class="btn btn-primary" id="card-button" @click="regist" >お支払</button> </div> </modal> </template> <script> import {loadStripe} from '@stripe/stripe-js'; export default { props: { product: { type: Object, }, request: { type: Object, }, public_key: { type: String, }, csrf: { type: String, } }, data() { return { stripe: null, stripeCard: null, Form: { cardHolderName: null, }, } }, methods: { setupStripe: async function() { this.stripe = await loadStripe(this.public_key); const elements = this.stripe.elements(); var style = { base: { color: "#32325d", fontFamily: '"Helvetica Neue", Helvetica, sans-serif', fontSmoothing: "antialiased", fontSize: "16px", "::placeholder": { color: "#aab7c4" } }, invalid: { color: "#fa755a", iconColor: "#fa755a" } }; this.stripeCard = elements.create('card', {style: style, hidePostalCode: true}); this.$nextTick(() => { this.stripeCard.mount('#card-element'); }); this.stripeCard.on('change', function(event) { var displayError = document.getElementById('card-errors'); if (event.error) { displayError.textContent = event.error.message; } else { displayError.textContent = ''; } }); }, regist: function() { console.log(this.request.product_id); //consoleに表示される console.log(this.product.id); //consoleに表示される this.stripe.createToken(this.stripeCard,{name: document.querySelector('#card-holder-name').value}).then(function(result) { if(result.error) { //エラーの処理 alert("エラー発生"); } else { //成功の処理 alert(result.token.id); //alertで出力される console.log(this.request.product_id); //★表示されない const url = '/shop/order_stripe'; let params = new FormData(); params.append('product_id', this.request.product_id); params.append('buy_address', this.request.buy_address); params.append('buy_address2', this.request.buy_address2); params.append('buy_email', this.request.buy_email); params.append('buy_name', this.request.buy_name); params.append('buy_namekana', this.request.buy_namekana); params.append('buy_num', this.request.buy_num); params.append('buy_phone', this.request.buy_phone); params.append('buy_post', this.request.buy_post); params.append('getinfo', this.request.getinfo); params.append('payment_method', this.request.payment_method); params.append('stripe_token', result.token.id); axios.post(url, params, { headers: { 'Content-Type': 'application/x-www-form-urlencode', } }) .then(response => { //console.log(this.request.product_id); /* if(response.data == 1) { alert("購入しました"); //location.href= ''; } else { alert(response.data); } */ }); } }); }, }, } </script>

いくつかテスト用にconsole.logをしています。
methodの中のregist関数直後の

console.log(this.request.product_id); console.log(this.product.id);

はconsoleに表示されますが、this.stripe.createTokenのthenの中、成功の処理のconsole.log(this.request.product_id);は表示される以下のエラーが出てしまいます。

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'request')

イメージ説明

同じrequest関数中なのに、エラーになってしまうのかがわかりません。。。thenの中だからでしょうか…(Javascript初心者です)

アドバイスいただけますと幸いです。
何卒、よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

createTokenthenメソッドをアロー関数式に変更してみて下さい

js

1/* 2 this.stripe 3 .createToken(this.stripeCard, { 4 //省略 5 }) 6 .then(function (result) { 7 //省略 8 }); 9*/ 10 11 this.stripe 12 .createToken(this.stripeCard, { 13 //省略 14 }) 15 .then((result) => { 16 //省略 17 });

詳しくは「アロー関数 this 評価」などで検索して下さい。

投稿2021/09/25 08:15

k4a

総合スコア983

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mikeko0901

2021/09/25 09:49

ありがとうございます!できました! アロー関数にすると、宣言元のthisを参照するのですね。勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問