Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

theluigi's avatar

Vue and Axios: Data is updated, but I cannot access it!

So I have this here Vue component, RegistrationForm.

<template>
    <div>

        <div class="mt-10 bg-white rounded shadow p-8">
            <h1 class="verygood-font text-2xl md:text-4xl">{{ event.title }}</h1>
            <p class="text-gray-600 text-lg my-2"><i class="fas fa-calendar-day"></i> {{ event.dates.human }}</p>
            <p class="text-gray-600 text-lg my-2"><i class="fas fa-map-marked-alt"></i> {{ event.location }}</p>
            <p class="text-gray-600 text-lg my-2"><i class="fas fa-money-bill-wave"></i> ${{ event.formatted_price }}</p>
        </div>

        <div class="mt-8">
            <form @submit.prevent="submitOrder()" method="post" :action="registerUrl" ref="payment-form">

                <div class="mt-8">
                    <h1 class="verygood-font text-3xl">Personal Information</h1>
                    <p class="my-2 text-lg text-gray-600">You're almost registered! We just need some information from you first. Let's start off with the basics, who are you?</p>
                </div>

                <div class="my-4">
                    <label class="text-lg text-gray-600">
                        Registrant name
                    </label>
                    <input v-model="order.name" placeholder="John Doe" name="name" class="bg-white rounded py-3 px-4 w-full mt-2 shadow">
                </div>

                <div class="my-4">
                    <label class="text-lg text-gray-600">
                        Registrant email
                    </label>
                    <input v-model="order.email" placeholder="[email protected]" name="email" type="email" class="bg-white rounded py-3 px-4 w-full mt-2 shadow">
                </div>

                <div class="mt-8">
                    <h1 class="verygood-font text-3xl">Addons</h1>
                    <p class="my-2 text-lg text-gray-600">This registration has several addons you can choose from. See if there's anything you might be interested in!</p>
                </div>

                <div class="my-4 text-gray-600">
                    <p class="my-2 text-lg">Would you like to add on a t-shirt to your registration?</p>
                    <div class="flex">
                        <button type="button" v-on:click="addShirtToOrder" class="bg-blue-500 hover:bg-blue-700 rounded my-auto px-4 py-2 text-white shadow">Yes, please!</button>
                    </div>
                </div>

                <div v-if="order.hasShirt" class="my-4 bg-white rounded shadow p-4">
                    <p class="text-gray-600">What size are you?</p>
                    <div class="inline-block relative w-64">
                        <select name="shirtSize" v-model="order.shirtSize" class="my-4 block appearance-none w-full bg-white border border-gray-400 hover:border-gray-500 px-4 py-2 pr-8 rounded shadow leading-tight focus:outline-none focus:shadow-outline">
                            <option>Please select a size!</option>
                            <option value="xs">Extra Small</option>
                            <option value="s">Small</option>
                            <option value="xm">Extra Medium</option>
                            <option value="m">Medium</option>
                            <option value="lg">Large</option>
                            <option value="xl">Extra Large</option>
                        </select>
                        <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">
                            <svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/></svg>
                        </div>
                    </div>
                    <div class="flex">
                        <a class="text-gray-500 my-auto hover:underline" v-on:click="removeShirtFromOrder">Actually, nevermind. I don't want a sweet t-shirt.</a>
                    </div>
                </div>


                <div class="mt-8">
                    <h1 class="verygood-font text-3xl">Payment Information</h1>
                    <p class="my-2 text-lg text-gray-600">All that's left is for you to pay for your registration! Make sure your registration looks good, and then checkout! You'll be good to go once you do!</p>
                </div>

                <div class="my-4">
                    <div>
                        <label class="text-lg text-gray-600">
                            Credit or debit card
                        </label>

                        <div class="bg-white rounded p-4 mt-2 shadow">
                            <div ref="card">
                                <!-- A Stripe Element will be inserted here. -->
                            </div>
                        </div>
                        <!-- Used to display Element errors. -->
                        <div id="card-errors" role="alert"></div>
                    </div>
                    <div>
                        <button type="submit" class="bg-blue-500 hover:bg-blue-700 w-1/3 rounded px-4 py-2 text-white mt-4 shadow">Register!</button>
                    </div>
                </div>

                <input type="hidden" name="_token" :value="csrf" />
                <input type="hidden" name="stripeToken" :value="order.stripeToken" />
                <input type="hidden" name="hasShirt" :value="order.hasShirt" />

            </form>

        </div>
    </div>
</template>

<script>

    let stripe = Stripe("pk_test_npgHJYXNKJ7Z0bm9RkGGUQa600nY0T59kW"),
        elements = stripe.elements(),
        card = undefined;

    export default {
        name: "RegistrationForm",
        data() {
            return {
                order: {
                    name: "",
                    email: "",
                    token: "",
                    hasShirt: false,
                    shirtSize: null,
                },

                errors: {},
                registerUrl: '/events/' + this.event.id + "/register"
            }
        },
        methods: {
            addShirtToOrder() {
                if(this.order.hasShirt == false) {
                    this.order.hasShirt = true;
                    this.order.total = this.order.total + 1500;
                }
            },

            removeShirtFromOrder() {
                if(this.order.hasShirt == true){
                    this.order.hasShirt = false;
                    this.order.total -= 1500;
                    this.order.shirtSize = null;
                }
            },

            submitOrder() {

                stripe.createToken(card).then(result => {
                    this.order.token = result.token.id;
                });

                axios({
                    method: 'post',
                    url: this.registerUrl,
                    data: this.order
                }).then((response) => {
                    console.log(response);
                })
                    .catch((error) => {
                        console.log(error);
                    });

            }
        },

        mounted() {
            card = elements.create('card');
            card.mount(this.$refs.card);
        },

        props: ['event', 'csrf']
    }
</script>

What I'm tryin' to do...

I attempt to generate a new payment token through Stripe when the user submits the form. I can successfully generate a token, and I see the token instantly in my VueJS dev tools for Chrome.

However when I go to post the order object in my Axios call to my server's backend, it doesn't show up in the request payload. It just shows up as an empty string when I can in fact see that it has a token in it within Devtools.

Happy to share any other information. I've been trying to get this to work for a couple days now and I'm ready to rip some hair out 😂

0 likes
2 replies
theluigi's avatar

AHHHHH THANK YOU SO MUCH

my hero, i owe you my life. 😂

Please or to participate in this conversation.