0

I'm trying to get a client token from the BrainTree API. I can establish a connection normally but when the code is executed the client token is always null. I've tried multiple solutions including this one here, but no luck.

The code is deployed in an Azure Function.

My Server Side Code :

module.exports = async function (context, req) {
const express = require("express");
const router = express.Router();

var braintree = require("braintree");
var clientToken;

        var gateway = new braintree.BraintreeGateway({
            environment: braintree.Environment.Sandbox,
            merchantId: 'xxxx',
            publicKey: 'xxxx',
            privateKey: 'xxx'
          }); 

    
    context.log('about to generate a client key');


    var Ctk = await gateway.clientToken.generate({}, (err, response) => {
         clientToken = response.clientToken
      });



    var responseC = "The Client token is  +" +clientToken;
    context.res = {
        body: responseC
    };
      context.log('client key generated');

}

Dimitris HD
  • 75
  • 1
  • 10

2 Answers2

0

The await keyword only works with functions that return Promise objects. While the Braintree documentation isn't 100% crystal-clear on this, the implication that's raised by switching the sample code on the linked page from "callbacks" to "Promises" is that when you specify a callback function via the second positional parameter a Promise isn't returned, thus nuking the value of using await in the first place. In this scenario, it doesn't work as you expect it and will continue to process asynchronously via the callback, which is why your clientToken isn't getting set the way you think it should.

If you're invested in using Promises all the way through, consider chaining the callback within a .then() call as the documentation prescribes. You also don't need to capture the return value of the call to generate(), as you're storing it in clientToken and not using Ctk at all.

await gateway.clientToken.generate({}).then((err, response) => {
    clientToken = response.clientToken
});
esqew
  • 42,425
  • 27
  • 92
  • 132
0

I have resolved this using the following code in the end.

It looks like braintree's functions are async and therefore we need to wait for them to complete. Promisify() did the job.

module.exports = async function (context, req) {
const express = require("express");
const router = express.Router();
var app = express();

var braintree = require("braintree");
var clientToken;

        var gateway = new braintree.BraintreeGateway({
            environment:  braintree.Environment.Sandbox,
            merchantId:   'xxx',
            publicKey:    'xxx',
            privateKey:   'xxx'
          }); 

          const util = require('util');
          const sale = util.promisify(gateway.clientToken.generate);

         result = await gateway.clientToken.generate({
          }).then(response => {
            // pass clientToken to your front-end
             clientToken = response.clientToken
          });

          var cToken= "client token is : " +clientToken;
          context.res = {
            body: cToken
        };

}

Dimitris HD
  • 75
  • 1
  • 10