Trouble With onCleanup()
I'm building a checkout flow with Stripe's embedded checkout form. It works like this.
The user clicks a "Buy Now" button on a products page that navigates to a checkout page.
The checkout page:
- Gets the product ID and quantity from the search params.
- Gets the checkout form from stripe
- Mounts the checkout form.
This works the first time I click a buy now button.
BUT
If I click back to the products page and click another buy now button, the checkout form doesn't load.
I'm getting an error from Stripe:
"You cannot have multiple embedded checkout items."
So, how do I "clear" or unmount the checkout form when I click the back button? I want to start fresh each time I click a buy now button. My use of onCleanup (below) isn't working.
Here's my checkout page:
17 Replies
i think it's because youre calling
onCleanup
after an await
solid's reactivity system works up until await
, after which point the reactive owner won't be present anymoreSo should I just move the onCleanup to the top of the createEffect?
i think that'd be the best solution yeah
though you may also need to remove the
async
from the effect as well, since i think that will immediately wrap everything in a promise that isn't part of the reactive contextYeah, but I need await for the call to my API endpoint.
Moving onCleanup up didn't work.
The check for the existence of checkoutElement also fails on the second load:
i think you'd need something like this - the
onCleanup
needs to be called synchronously
though i think this could suffer a race condition where cleanup could happen before the checkout is made, and then the checkout wouldn't end being unmounted
i wonder if createResource would be a better option hereI'm not sure. I've got to run for a bit. I'll keep plugging away at this and see if anyone else chimes in with some ideas.
ah i think this will do it
Unfortunately, no. Same error.
ah - it'll at least avoid the race condition 😅
Haha
The check for the existence of checkoutElement also fails on the second loadhow are you creating
checkoutElement
?Seems like a problem @peerreynders could solve in his sleep. Haha.
That's at least how the docs suggest to do it: https://docs.solidjs.com/concepts/refs#refs
yeah that's a fine way to do it
ah i think you need to
destroy
not unmount
checkout.destroy() Removes Checkout from the DOM and destroys it. Once destroyed, an embedded Checkout instance cannot be reattached to the DOM. Call checkout.initEmbeddedCheckout to create a new embedded Checkout instance after unmounting the previous instance from the DOM.
You're a genius!
That works. Where did you get destroy from? A quick search in the docs and I don't see it mentioned.
Oh!!! I was thinking destroy was from solid. Duh
Great. Can't thank you enough. I was fighting this for a couple of hours.
Stripe works great, but their docs are very dense. It's easy to miss things.
Thanks again!
yeah there's a lot to keep track of haha, glad it's fixed for ya