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

usman9023's avatar

How can I solve the 'Cannot read properties of undefined' error while using Stripe checkout in Vue.js component?

Im Working on Full stack web application for backend im using laravel and for frontend im using VUE js . Now my issue is in Vue . Im adding Stripe payment gateway in my application. Everything is working fine but whenver i add

 <stripe-checkout
                        ref="checkoutRef"
                        :pk="publishableKey"
                        :sessionId="sessionId"
                      />

above line in my Vue code im starting to get this error :

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

and this line is necessary for stripe checkout

I tried adding div around the component but the error is not removed whenever i removed the component my application works fine but i have to add the stripe component in order to stripe checkout works

Here is my full code :

  <div class="wrapper">
    <TopNavigationComponent />
    <SidebarComponent class="main-sidebar" />

    <div class="content-wrapper">
      <div class="d-flex justify-content-center">
        <div class="col-md-10">
          <div class="card card-primary">
            <div class="card-header">
              <h3 class="card-title">Cab Booking</h3>
            </div>

            <div class="card-body">
              <div class="row">
                <div class="col-md-6">
                  <form @submit.prevent="handleSubmit" class="form-horizontal">
                    <div class="form-group">
                      <label for="name">Name:</label>
                      <input
                        type="text"
                        id="name"
                        v-model="booking.name"
                        class="form-control"
                        :class="{ 'is-invalid': nameError }"
                        placeholder="Name"
                      />
                      <div v-if="nameError" class="invalid-feedback d-block font color">
                        {{ nameError }}
                      </div>
                    </div>
                    <div class="form-group">
                      <label for="phone">Phone Number:</label>
                      <input
                        type="tel"
                        id="phone"
                        v-model="booking.phone"
                        class="form-control"
                        :class="{ 'is-invalid': phoneError }"
                        placeholder="Phone Number"
                      />
                      <div v-if="phoneError" class="invalid-feedback d-block font color">
                        {{ phoneError }}
                      </div>
                    </div>
                    <div class="form-group">
                      <label for="email">Email:</label>
                      <input
                        type="email"
                        id="email"
                        v-model="booking.email"
                        class="form-control"
                        :class="{ 'is-invalid': emailError }"
                        placeholder="Email"
                      />
                      <div v-if="emailError" class="invalid-feedback d-block font color">
                        {{ emailError }}
                      </div>
                    </div>
                    <div class="form-group">
                      <label for="departure-date">Departure Date and Time:</label>
                      <input
                        type="datetime-local"
                        id="departure-date"
                        v-model="booking.departureDateTime"
                        class="form-control"
                        :class="{ 'is-invalid': datetimeError }"
                      />
                      <div v-if="datetimeError" class="invalid-feedback d-block font color">
                        {{ datetimeError }}
                      </div>
                    </div>
                    <div class="form-group">
                      <label for="return-date">Return Date and Time:</label>
                      <input
                        type="datetime-local"
                        id="return-date"
                        v-model="booking.returnDateTime"
                        class="form-control"
                        :class="{ 'is-invalid': returnDateTimeError }"
                      />
                      <div v-if="returnDateTimeError" class="invalid-feedback d-block font color">
                        {{ returnDateTimeError }}
                      </div>
                    </div>
                    <div class="form-group">
                      <label for="cars">Cars:</label>
                      <select
                        id="cars"
                        v-model="booking.car"
                        class="form-control"
                        :class="{ 'is-invalid': carError }"
                      >
                        <option value="">Select a car</option>
                        <option v-for="car in cars" :value="car.carTitle" :key="car.id">
                          {{ car.carTitle }}
                        </option>
                      </select>
                      <div v-if="carError" class="invalid-feedback d-block font color">
                        {{ carError }}
                      </div>
                    </div>

                    <router-link to="/dashboard">
                      <button class="btn btn-primary button" type="button">Cancel</button>
                    </router-link>

                    <button class="stripe-button" @click="submit">Pay now!</button>
                    <div>
                      <stripe-checkout
                        ref="checkoutRef"
                        :pk="publishableKey"
                        :sessionId="sessionId"
                      />
                    </div>
                    <button type="submit" class="paypal-button">
                      <i class="paypal-logo">Pay</i><i class="paypal-logo">Pal</i>
                    </button>
                  </form>
                </div>
                <div class="col-md-6">
                  <div class="booking-details">
                    <h2>Booking Details</h2>
                    <p><strong> Name:</strong> {{ booking.name }}</p>
                    <p><strong>Phone Number:</strong> {{ booking.phone }}</p>
                    <p><strong>Email:</strong> {{ booking.email }}</p>
                    <p><strong>Departure Date and Time:</strong> {{ booking.departureDateTime }}</p>
                    <p><strong>Return Date and Time: </strong>{{ booking.returnDateTime }}</p>
                    <p><strong>Car:</strong> {{ booking.car }}</p>
                    <p><strong>Price:</strong> {{ getPrice() }} $ /hr</p>
                    <p><strong>Total Bill:</strong> {{ calculateBill.toFixed(0) }} $</p>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, onMounted, computed } from 'vue'
import axios from 'axios'
import API_URL from '@/config'
import SidebarComponent from '@/components/SidebarComponent.vue'
import TopNavigationComponent from '@/components/TopNavigationComponent.vue'
import { toast } from 'vue3-toastify'
import 'vue3-toastify/dist/index.css'
import { useRouter, useRoute } from 'vue-router'
import { StripeCheckout } from '@vue-stripe/vue-stripe'

export default {
  components: {
    SidebarComponent,
    TopNavigationComponent,
    StripeCheckout
  },

  setup() {
    const booking = ref({
      name: '',
      phone: '',
      email: '',
      departureDateTime: '',
      returnDateTime: '',
      car: ''
    })
    const cars = ref([])
    const nameError = ref(null)
    const phoneError = ref(null)
    const emailError = ref(null)
    const datetimeError = ref(null)
    const returnDateTimeError = ref(null)
    const carError = ref(null)
    const route = useRoute()
    const router = useRouter()
    const publishableKey =
      'pk_test_51NE6AVBIPVlJ4mt0xjpNsBF37Dus99OLspog6U4DYOlGa7XTmZumxf3KGzJXCuSGm1C7jv7sCxZatK3fw6jA66CD004S3P4pqS'
    const sessionId = ref(null)
    const checkoutRef = ref(null)

    const getSession = () => {
      axios
        .get(`${API_URL}/getSession`)
        .then((res) => {
          sessionId.value = res.data.id
        })
        .catch((err) => {
          console.log(err)
        })
    }
    const submit = () => {
      if (sessionId.value && checkoutRef.value) {
        checkoutRef.value.redirectToCheckout()
      }
    }
    const fetchCars = async () => {
      try {
        const response = await axios.get(`${API_URL}/listofcars`)
        cars.value = response.data
      } catch (error) {
        console.error(error)
      }
    }

    onMounted(() => {
      fetchCars()
      getSession()

      const paymentSuccess = route.query.success === 'true'
      const paymentFailure = route.query.success === 'false'

      if (paymentSuccess) {
        toast.success('Your Booking Has Been Successful', {
          position: 'top-right',
          autoClose: 5000,
          hideProgressBar: false,
          closeOnClick: true,
          pauseOnHover: true,
          draggable: true,
          progress: undefined,
          theme: 'colored'
        })
        router.replace({ query: { ...route.query, success: undefined } })
      } else if (paymentFailure) {
        toast.error('Booking failed. Please try again.', {
          position: 'top-right',
          autoClose: 5000,
          hideProgressBar: false,
          closeOnClick: true,
          pauseOnHover: true,
          draggable: true,
          progress: undefined,
          theme: 'colored'
        })
        router.replace({ query: { ...route.query, success: undefined } })
      }
    })

    const calculateBill = computed(() => {
      const selectedCar = cars.value.find((car) => car.carTitle === booking.value.car)
      if (selectedCar) {
        const departure = new Date(booking.value.departureDateTime)
        const returnDate = new Date(booking.value.returnDateTime)
        const hours = Math.abs(returnDate - departure) / 36e5
        return selectedCar.price * hours
      }
      return 0
    })
    const getPrice = () => {
      const selectedCar = cars.value.find((car) => car.carTitle === booking.value.car)
      return selectedCar ? selectedCar.price : ''
    }

    const handleSubmit = async (e) => {
      e.preventDefault()

      nameError.value = null
      phoneError.value = null
      emailError.value = null
      datetimeError.value = null
      returnDateTimeError.value = null
      carError.value = null

      if (!booking.value.name) {
        nameError.value = 'Name is required'
      }
      if (!booking.value.phone) {
        phoneError.value = 'Phone No is required'
      }
      if (!booking.value.email) {
        emailError.value = 'Email is required'
      }
      if (!booking.value.departureDateTime) {
        datetimeError.value = 'Departure Date & Time is required'
      }
      if (!booking.value.returnDateTime) {
        returnDateTimeError.value = 'Return Date & Time is required'
      }
      if (!booking.value.car) {
        carError.value = 'Please Select a Car For Checkout'
      }

      if (
        !booking.value.name ||
        !booking.value.phone ||
        !booking.value.email ||
        !booking.value.departureDateTime ||
        !booking.value.returnDateTime ||
        !booking.value.car
      ) {
        return
      }

      let formData = new FormData()
      formData.append('name', booking.value.name)
      formData.append('phone', booking.value.phone)
      formData.append('email', booking.value.email)
      formData.append('departure-date', booking.value.departureDateTime)
      formData.append('return-date', booking.value.returnDateTime)
      formData.append('cars', booking.value.car)
      formData.append('totalBill', calculateBill.value.toFixed(0))

      try {
        const response = await axios.post(`${API_URL}/payment/initiate`, formData)

        if (response.status === 200) {
          const data = response.data.redirect_url
          window.location.href = data
        }
      } catch (error) {
        toast.error('An error occurred while booking the car', {
          position: 'top-right',
          autoClose: 5000,
          hideProgressBar: false,
          closeOnClick: true,
          pauseOnHover: true,
          draggable: true,
          progress: undefined,
          theme: 'colored'
        })
      }
    }

    return {
      booking,
      cars,
      handleSubmit,
      getPrice,
      calculateBill,
      nameError,
      phoneError,
      emailError,
      datetimeError,
      returnDateTimeError,
      carError,
      publishableKey,
      sessionId,
      checkoutRef,
      submit
    }
  }
}
</script>

0 likes
1 reply
vincent15000's avatar

Somewhere in your code, you are trying to get a property of an undefined object.

For example, image you have the category property and you want to retrieve the name of the category with category.name. If category is undefined, you would try to read the name of an undefined object.

To solve your problem, you need to search inside your code where you are trying to get a property from an undefined object.

Additionnally to this error, you probably have some further information like the file and the line where the problem occurs.

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

Please or to participate in this conversation.