Encountering a problem with Vue StripeCheckout while navigating to a different component

I'm looking to integrate the StripeCheckout component into my Vue application. After copying and updating their example code using the composition API from here, everything works fine when I route to the subscribe component. However, if I try to navigate to a different component after rendering the subscribe page, an error occurs while trying to unmount the StripeCheckout component.

Error Message:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '__asyncLoader')
    at isAsyncWrapper (runtime-core.esm-bundler.js?d2dd:2243:1)
    at unmount (runtime-core.esm-bundler.js?d2dd:6061:1)
    at unmountComponent (runtime-core.esm-bundler.js?d2dd:6183:1)
    at unmount (runtime-core.esm-bundler.js?d2dd:6068:1)
    at unmountChildren (runtime-core.esm-bundler.js?d2dd:6212:1)
    at unmount (runtime-core.esm-bundler.js?d2dd:6086:1)
    at unmountComponent (runtime-core.esm-bundler.js?d2dd:6183:1)
    at unmount (runtime-core.esm-bundler.js?d2dd:6068:1)
    at unmountChildren (runtime-core.esm-bundler.js?d2dd:6212:1)
    at unmount (runtime-core.esm-bundler.js?d2dd:6086:1)

Subscribe Component Code:

<template>
  <div>
    <stripe-checkout
      ref="checkoutRef"
      mode="subscription"
      :pk="publishKey"
      :line-items="lineItems"
      :success-url="successUrl"
      :cancel-url="cancelUrl"
      @loading="(v) => (this.loading = v)"
    />
    <button @click="submit">Subscribe!</button>
  </div>
</template>

<script lang="ts" setup>
import { StripeCheckout } from "@vue-stripe/vue-stripe";
import { ref } from "vue";
import { EnvironmentVariableManager } from "@/utils/environment-variable-manager";

const publishKey = EnvironmentVariableManager.getStripePublishableKey();
const loading = ref(false);
const lineItems = [
  {
    price: "price_1MLUEMLQEklYWrzRVqxFJqt8",
    quantity: 1,
  },
];

const successUrl = EnvironmentVariableManager.getUrl() + "/subscribe";
const cancelUrl = EnvironmentVariableManager.getUrl() + "/subscribe";

const checkoutRef = ref<StripeCheckout | null>(null);

const submit = () => {
  if (checkoutRef.value) {
    checkoutRef.value.redirectToCheckout();
  } else {
    console.error("Checkout ref not found");
  }
};
</script>

Router Setup:

const routes = [{
    path: "/subscribe",
    name: "Subscribe",
    component: HomeView,
    children: [{ name: "Subscribe", path: "", component: Subscribe }],
  },
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

While researching, I found that with StripeElements, you can call the destroy function before unmounting components. I'm wondering if something similar needs to be implemented for StripeCheckout, although there are no documented functions for this purpose. Any insights on why StripeCheckout triggers an exception during routing/unmounting?

Answer №1

I've encountered the same issue and while I haven't found a permanent solution yet, I have discovered a temporary workaround that has been effective for me.

     <stripe-checkout
      v-if="readyToPay"
      ref="checkoutRef"
      mode="subscription"
      :pk="publishKey"
      :line-items="lineItems"
      :success-url="successUrl"
      :cancel-url="cancelUrl"
      @loading="(v) => (this.loading = v)"
    /> 
    ...
    <script>
     export default {
     name: "Packages",
     data(){return{readyToPay:false}}
     }
    </script>

Then, I utilize a submit function for the payment button to activate the stripe-checkout component, allowing it to display and proceed with the payment process afterwards.

      async submit() {
      this.readyToPay = true;
      await this.$nextTick();
      ...
      }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Determine an expression based on a string in Typescript

Looking at the code snippet below, everything appears to be in order (view playground): type PathParam<T> = T extends `${string}:${infer U}` ? U : never; type Param = PathParam<"/post/:post_id">; // type Param = "post_id" ...

Angular Pagination: Present a collection of pages formatted to the size of A4 paper

Currently, I am working on implementing pagination using NgbdPaginationBasic in my app.module.ts file. import { NgbdPaginationBasic } from './pagination-basic'; My goal is to create a series of A4 size pages with a visible Header and Footer onl ...

Issue: Typescript/React module does not have any exported components

I'm currently facing an issue with exporting prop types from one view component to another container component and using them as state type definitions: // ./Component.tsx export type Props { someProp: string; } export const Component = (props: ...

The functionality of selecting all items in v-select does not result in saving all of them

I'm currently working on integrating a select all button into the v-select component of Vuetify. The issue I am facing is that even though I can use the button to select all options, when I attempt to save, not all items are saved. However, if I manua ...

Generate an object in Typescript that includes a dynamic property calculated from an input parameter

Is there a way to achieve the following function in TypeScript? function f<T extends 'a' | 'b'>(t : T): {[t]: ...} { return {[t]: ...} } This code is intended to make f('a') have type {'a': ...} and similarl ...

Regular expressions that identify text located at the conclusion of a URL

Although the title may not be entirely appropriate, my goal is to create a regex that will remove any trailing '/' at the end of a URL under certain conditions. For example: http://stackoverflow.com/questions/ask/ to http://stackoverflow.com/qu ...

How can I modify the query parameter value in vue-router?

router.push({ path: 'register', query: { plan: 'private' } }) will create a URI like: http://localhost:3000/#/register?plan=private&plan=public in case the query parameter with key plan and value public already exists in $currentR ...

What is the best way to conceal a global component like a navbar on specific routes?

Most of the pages on my vuejs SPA feature a top navbar component, but there are certain views like the login page where I do not want it to be displayed. My current solution involves importing the navbar and adding it to each view separately when needed. ...

Vue Selecting Several Options

I am looking to implement multiple selections without using the multiple.vue library. I want to create my own solution. In JavaScript, I have data structured like this: data: roles : [here data] form.roles: [] And here is how I am handling it in m ...

Utilize functional JS code within a TypeScript environment

Attempting to integrate this code into a TypeScript project, it is a modified version of the react-custom-scrollbars. I am struggling with TypeScript in regards to declaring types for style and props. In this particular case, I prefer to bypass type check ...

Implementing a ReactJS component with a TypeScript interface for displaying an Alert box message using Material

I have a MUI Alert box in my application where I am trying to change the message inside with an href URL. However, when I use the herf tag, it shows as text instead of a link. How can I make it display as an actual link? In the code below, when I click th ...

Vuetify does not support Tailwind CSS styles

Initially, I integrated Tailwind CSS into my project. However, during the development process, I decided to give Vuetify a try. After adding Vuetify along with vuetify-loader, I encountered an issue where Vuetify functionality was working fine but the styl ...

Accessing a data property within an Angular2 route, no matter how deeply nested the route may be, by utilizing ActivatedRoute

Several routes have been defined in the following manner: export const AppRoutes: Routes = [ {path: '', component: HomeComponent, data: {titleKey: 'homeTitle'}}, {path: 'signup', component: SignupComponent, data: {titleKe ...

What are some alternatives for integrating React production build files apart from utilizing Express?

Is there a way to integrate React into my library using the HTTP module? I'm trying to figure out how to recursively send static files. Specifically, I want to include the build folder from the React production build, but I'm not sure how to go a ...

Utilizing Nuxt Compostion API to Swap Classes on Hover

<script setup> import Logo from "../assets/svgs/Logo"; import Menu from "../assets/svgs/Menu"; const hover = Boolean let boxTop if (hover === true) { boxTop = 'boxTop--0' } else { boxTop = 'boxTop--20' } ...

Understanding the concept of inconsistent return points in Typescript: What implications does it carry?

I am currently working on converting a NodeJs JavaScript code to TypeScript. The code snippet below shows how I save uploaded files using JavaScript and now I'm encountering an error when trying to do the same in TypeScript. The error message says "Fu ...

Unable to destructure props and assign them to a react-bootstrap component

I recently installed react-bootstrap and I am looking to customize the default buttons in my project. My goal is to simplify the button creation process by just using <Button> without specifying a variant option for most buttons. import * as bs from ...

Implementing multiple components in a Vue route: A comprehensive guide

As a beginner in Vue, I am experimenting with incorporating two components in a route - a navigation bar and some sales data. The assets are being bundled by Laravel mix using Webpack, but I keep encountering failures with npm. index.php <body> ...

What is the most efficient method for referencing nested descendants with ref in Vue? (Ancestor - Parent - Child)

Due to the unique project structure that cannot be changed, I am faced with the need to retrieve a value from a grandfather component all the way down to the grandson (Grandfather to Son's son relationship). The following code snippet illustrates this ...

VueJs: Incorporating one component within another for enhanced functionality

I am attempting to utilize the main component inside another one with pre-defined properties, but I am encountering an issue where the div is empty. Below is the code snippet that I am working with: <template> <call-dialog-link :id=" ...