"requestPaymentMethod()" Intermittently Throws an Error When Called in "braintree.dropin.create()" Callback
See original GitHub issueGeneral information
- SDK/Library version: 1.10.0
- Environment: Sandbox
- Browser and OS: Chrome Version 66.0.3359.139 (Official Build) (64-bit) on MacOS MacOS 10.12.3
How I Arrived at the Issue
A user who has a “requestable” payment (a payment method available from the vault) arrives on a page and is presented with the below UI (note the Pay
button is coming from my application):
This is based on the example code as shown in the README.md
file of this repo:
var submitButton = document.querySelector('#submit-button');
braintree.dropin.create({
authorization: 'CLIENT_AUTHORIZATION',
selector: '#dropin-container'
}, function (err, dropinInstance) {
if (err) {
// Handle any errors that might've occurred when creating Drop-in
console.error(err);
return;
}
submitButton.addEventListener('click', function () {
dropinInstance.requestPaymentMethod(function (err, payload) {
if (err) {
// Handle errors in requesting payment method
}
// Send payload.nonce to your server
});
});
});
Below is the flow that seems awkward to me for this type of user:
- The user clicks the “Pay” button which calls
instance.requestPaymentMethod()
even though the user already has a payment method… so we can get the payment nonce. - The user has to interact with the application again in order to submit the payment. My app is using the same button and changing the text to “Confirm” (see below).
This a bit awkward because nothing changes except the text of the button from “Pay” to “Confirm” and requires one extra unnecessary click to complete the order. I’m only doing that so the user sees something change.
So, I thought I could simply check if we have a requestable payment on the callback of dropin.create()
, and if so - just execute instance.requestPaymentMethod()
without any user interaction. Something like the below code is what could accomplish that and is where the bug is reproducible:
var submitButton = document.querySelector('#submit-button');
braintree.dropin.create({
authorization: 'CLIENT_AUTHORIZATION',
selector: '#dropin-container'
}, function (err, dropinInstance) {
if (err) {
// Handle any errors that might've occurred when creating Drop-in
console.error(err);
return;
}
if (dropinInstance.isPaymentMethodRequestable()) {
dropinInstance.requestPaymentMethod(function (err, payload) {
if (err) {
// Handle errors in requesting payment method
}
// Send payload.nonce to your server
});
}
// do whatever you want...
// ...
});
Issue description
When calling instance.requestPaymentMethod()
within the braintree.dropin.create()
callback function an error intermittently occurs (I can reproduce approximately 1 out of every 5 page loads). Above is an example of code that reproduces the issue.
Below is the error output from Chrome Developer Tools:
dropin-1.10.0.min.js:7 Uncaught TypeError: Cannot read property 'requestPaymentMethod' of undefined
at i.requestPaymentMethod (dropin-1.10.0.min.js:7)
at i.requestPaymentMethod (dropin-1.10.0.min.js:5)
at i.requestPaymentMethod (dropin-1.10.0.min.js:1)
at requestPaymentMethod (braintree.js:23)
at braintree.js:50
at dropin-1.10.0.min.js:1
Strange (probably unreliable) workaround
I did discover that when I change this from the example above:
if (dropinInstance.isPaymentMethodRequestable()) {
dropinInstance.requestPaymentMethod(function (err, payload) {
// ...
});
}
To this:
if (dropinInstance.isPaymentMethodRequestable()) {
setTimeout(function() {
dropinInstance.requestPaymentMethod(function (err, payload) {
// ...
});
}, 200);
}
… The issue is no longer reproducible (in my testing with Chrome). This tells me there is probably some kind of race condition in the dropin UI library.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:2
- Comments:15 (6 by maintainers)
Top GitHub Comments
Please fix this finally!!!
Thanks for the info. I’ll take another look at this soon.