Closed NinoSkopac closed 1 year ago
Thanks for asking about this!
We have a teardown()
function that you should call to destroy Drop-in. Example:
var dropinInstance;
braintree.dropin.create({
// ...
}, function (err, dropin) {
// ...
dropinInstance = dropin;
});
// Destroy Drop-in
dropinInstance.teardown(function(err) {
if (err) { console.error('An error occurred during teardown:', err); }
});
We'll add documentation of this to our README.
Removing the click event listener is fine. Here's an alternative:
var dropinInstance;
braintree.dropin.create(/* ... */, function(err, dropin) {
// ...
dropinInstance = dropin;
});
_submitButton.addEventListener('click', function () {
dropinInstance.requestPaymentMethod(/* ... */);
});
The click event listener here uses dropinInstance
, which you can overwrite at any time.
Does this help?
Looks good, I'll use your method then.
Great! Thanks again for pointing out this issue.
I'm using braintree web drop in with Vue.js and I'm having an issue where I call the teardown method on my destroy life cycle hook (when I leave the checkout screen that has the drop in) and the teardown method gets called without producing any errors. However, when I go back to my checkout screen and reinitialize my dropin, I get the following error:
DropinError {name: "DropinError", message: "options.selector or options.container must reference an empty DOM node.", _braintreeWebError: undefined}
(warning) PayPal Checkout Integration Script already loaded on page
Is there something that I'm doing incorrectly?
@aphavichitr My guess is that Vue is removing the view from the DOM before Drop-in can succesfully remove itself. When you return to the checkout page, Vue re-inserts the view with the non-empty DOM node.
If you provide a demo app on Github that reproduces the issue, I'm happy to see if I can tweak the lifecycle hooks to work correctly with Drop-in, but if you want a quick solution, simply emptying the DOM node before calling create should do it.
var myContainer = document.getElementById('my-container');
myContainer.innerHTML = '';
braintree.dropin.create({
authorization: myAuth,
container: myContainer
}, callback);
The checkout.js warning is nothing to be concerned about, but I will see about silencing that warning.
@crookedneighbor Thanks for the solution. I tried it and it didn't work because It turned out to be an issue with the EventBus I was using and not related to the lifecycle hooks or the drop in listeners getting tore down. I had an EventBus in my created lifecycle hook that initialized the braintree dropin after the api response from getting the client token. I didn't remove the EventBus listeners with EventBus.$off in the beforeDestroy lifecycle hook when navigating away from the page, so every time I returned to the Checkout component, it would create a new EventBus listener and therefore keep reinitializing an extra braintree dropin for the number of times I've been on the page without a refresh. I probably should avoid using the EventBus, but I haven't figured out a way to get the client token asynchronously before initializing the drop in, since I'm getting the client token and initializing the drop in in sibling components.
@aphavichitr Are you vaulting with Drop-in? If not, you could always use a tokenization key, so you don't need to fetch a client token at all.
@crookedneighbor Not vaulting with drop-in. Thanks, I'll take a look at the tokenization key.
I have the problem with Vue.js, too. When switching fast between routes, the DOM element with id="braintree
gets removed before the initialization can happen.
The teardown
function won't help since the creation isn't finished, yet.
Repository to reproduce:
https://github.com/ndabAP/braintree-vue-routes-issue
Steps
$ yarn # or npm i
src/views/BraintreeWebDropIn.vue
line 8$ yarn serve # or npm run serve
Other route
before three seconds passedHi @ndabAP, thanks for your example, it made reproducing the issue super easy. There are a few ways we could go about fixing this, but it seems like the best strategies might require a few breaking changes and therefore a major version bump. There are a few other major version bump changes we want to make soon, so we'll add this one to the list.
There are some less attractive patches that might do the trick, and we'll put some time into tracking those to see if there's something that can be done in the near future. As you said, currently there's no way to cancel the setup, but you should be fine to just ignore that error as a temporary workaround.
@jackellenberger I really appreciate your openness and the given insight in your development.
Any updates?
Hey @ndabAP, we played around with patching this in the current major version and weren't really happy with any of the solutions, so we're planning on fixing this issue the right way™ in the next major version. We don't have an ETA for that yet, but it is being worked on and should include a solution for this issue. Thanks for your patience!
Thanks a lot for your fast feedback.
closing for inactivity. If you continue to encounter errors, please contact Support
I think you guys should expose a drop-in API for destroying the thing, cause as it is, we have to do it ourselves and it can be a pain, since simply emptying the container will keep the event handler bound to the purchase button, meaning the
requestPaymentMethod
will be called multiple times.This is how I used to do it (which was buggy since it would trigger the requestPaymentMethod multiple times upon re-creating it):
Now I do it like this, which works almost perfectly:
What I'm doing is I'm using removeEventListener to get rid of the current click handler when destroying it.
Is this a good approach? Pls don't laugh at my JS, I'm a PHP guy :D