How to Promisify this function - nodejs [duplicate]
Asked Answered
Z

3

16

I have an ajax call which needs to return a promise. The function is as follows

client.tickets.create(ticket,  function(err, req, result) {
  if (err) {    
    logger.error(err);

    return false;
  }

  return JSON.stringify(result);
});

I have to wait for this function to execute before I can perform the next action. How can I promisify this function ?

I tried the following and it gave me an error saying Cannot call method then of undefined:

return client.tickets.create(ticket).then(function(result){
    return JSON.stringify(result);
},function(err){
    logger.error(err);
    return false;
});
Zingale answered 12/1, 2016 at 6:12 Comment(1)
du u use any promise api?Marthena
D
42

You have the error because create() is not a Promise. Promisifying an async function is quite easy (nodejs has a built-in Promise support nowadays):

function createTicket(ticket) {
    // 1 - Create a new Promise
    return new Promise(function (resolve, reject) {
        // 2 - Copy-paste your code inside this function
        client.tickets.create(ticket, function (err, req, result) {
            // 3 - in your async function's callback
            // replace return by reject (for the errors) and resolve (for the results)
            if (err) {
                reject(err);
            } else {
                resolve(JSON.stringify(result));
            }
        });
    });
}

// 4 - consume your promise with then() (resolved promise) and catch (rejected promise)
createTicket(ticket).then(function (result) {
    // deal with result here
}).catch(function (err) {
    // deal with error here
});
Diastole answered 12/1, 2016 at 6:22 Comment(1)
In release candidate for Node.js 8.0.0, there's a new utility, util.promisify, that encapsulates the capacity of promisifying whatever function. It is not much more different from the approaches suggested in the other answer, but has the advantage of being a core method. You may want to read more in this postTannatannage
N
10

rather than manually wrapping async code into promises, I would advice using libraries like Bluebird to do that for you:

var Bluebird = require('bluebird');

//either 
client.tickets = Bluebird.promisifyAll(client.tickets);
//or 
client.tickets.createAsync = Bluebird.promisify(client.tickets.create);
...
    return client.tickets.createAsync(ticket)
      .then(JSON.stringify)
      .catch(err => {
        logger.error(error); 
        return false
      });
Nitrate answered 12/1, 2016 at 7:18 Comment(0)
M
-3
function createTicket(){
var deferred = Q.defer()
client.tickets.create(ticket,  function(err, req, result) {
     if (err) { 
                logger.error(err);
                return deferred.reject(err)
            }
   return deferred.resolve(result)
});
}

createTicket().then(function(){
    //success here
}, function(){
    //failure here
});

Using Q api you can achive promise.

Marthena answered 12/1, 2016 at 6:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.