dimanche 4 avril 2021

Flutter - waiting for JavaScript Promise

I'm trying to integrate Braintree payments for my Flutter application. I have a plugin to handle iOS/Android and am writing a custom implementation for web.

It's a fairly simple solution I think, I'm using the Braintree Javascript SDK/Drop in UI (GitHub tutorial) to render the payment screen using HTML. This part I got working, however to properly process these payments I need to retrieve the response of the JavaScript function - specifically a string the payment nonce.

To do this i used some channel methods and dart magic to call this javascript function

async function payment(auth) {
 braintree.dropin.create({
   authorization: auth,
   selector: '#dropin-container'
 }, function (errCreate, instance) {
    document.getElementById("submit-button").addEventListener('click', function () {
        if(errCreate) {
            console.log("Error", errCreate);
            return;
        }
        instance.requestPaymentMethod(function (requestPaymentMethodErr, payload) {
            if (requestPaymentMethodErr) {
                console.log('Error', requestPaymentMethodErr);
                return;
            }
            return payload.nonce;
        });
    });
});
}

This function seems to be working, returning data and payment nonces and all that. In a (separate) dart file where I'm actually rendering the widget, I declared the function like so:

// EXTERNAL JAVASCRIPT ==========================================

@JS()
external void initBraintree(auth);

@JS()
external payment(String auth);

and this seems to be working, it's calling the function on button click so that's good. The issue is when I call this async function it returns a promise, theoretically dart should not have any idea how to handle this however, they thankfully have a method called promiseToFuture that should handle just this. I've used it like so:

  Future<BraintreeDropInResult> start(BuildContext context, BraintreeDropInRequest request) async {
    // create div with html embedded
    String htmlL = """<div id="checkout-message"></div>
        <div id="dropin-container"></div>
    <button id="submit-button">Submit payment</button>""";
    var paymentDiv = html.DivElement()..appendHtml(htmlL);

    // attach to payment container
    ui.platformViewRegistry.registerViewFactory('braintree-container', (int viewId) => paymentDiv);

    // call js function
    var promise = payment(request.clientToken);
    String nonce = await promiseToFuture(promise);
 ...

However it just does not work. The JavaScript function seems to be returning a promise object however the promiseToFuture function never waits for it, just instantly returns null everytime.

Been working on this a while and finally feel really close but this is being a real thorn in my side so any help is really appreciated!




Aucun commentaire:

Enregistrer un commentaire