2
\$\begingroup\$

I was trying to use the ES6 Promise with the "co" module to write the async code without callback. Though actual async call is neat and clean, I still have to add wrapper method to return Promise object which made it little bulky. Any feedback to improve this code quality will be appreciated.

crud.js
'use strict';
const db = require("./dbmanager").db;
const co = require("co");

module.exports = {

  getAllDocuments: (collectionName)=> {

    //This line of code returning "Promise" object make code bulky. Now I have two wrapper, one for "Promise" and second for "co".
    return new Promise((resolve, reject) => {

      co(function*() {
        let docs = yield db.collection(collectionName).find().toArray();
        resolve(docs);

      }).catch((err) => {
        reject(err);
      });

    });
  }

}; 

book.js

'use strict';
const dbcrud   = require("./../mongodb/crud");
const co = require("co");
module.exports = {

  getTransactions: (callback) => {
    co(function*() {

      var books = yield dbcrud.getAllDocuments('books');
      callback(null, books);

    }).catch((err) => {
      console.log("Error " + JSON.stringify(err));
      callback(err, null);
    });
  }

};
\$\endgroup\$
  • \$\begingroup\$ Does this work? It doesn't look like it should... .find() normally doesn't return something you can call .toArray() on. \$\endgroup\$ – Madara Uchiha May 17 '16 at 20:13
  • \$\begingroup\$ yes, it works. I am doing the poc code and for now its working. \$\endgroup\$ – joy May 17 '16 at 20:24
  • \$\begingroup\$ Doesn't co return a promise? \$\endgroup\$ – Kevin B May 17 '16 at 20:38
  • \$\begingroup\$ Don't know. Document of "co" doesn't show it does. Need to explore more. \$\endgroup\$ – joy May 17 '16 at 21:47
3
\$\begingroup\$

After going through the "co" GitHub code, I was able to remove the extra boilerplate code. I made following changes to improve my code:

  1. Used the "co" promise and return it in my async function. This help to remove the extra "Promise" wrapper code.
  2. To resolve the "co" promise, I returned the "Promise" as per fails/success scenario.
  3. When making call to MongoDB native driver, used ".catch" to catch the error there itself and apply logic.

Following is my final version which is neater and cleaner using the "co" module:

crud.js

'use strict';
const db = require("./dbmanager").db;
const co = require("co");

module.exports = {

  getAllDocuments: (collectionName)=> {
      //return the "co" promise instead of using "Promise" boilerplate code
      co(function*() {
        let docs = yield db.collection(collectionName).find().toArray().catch(function(err) {
        //in case of error, return the custom message and log the error returned by mongodb driver
        console.log('Error occurred to get documents', err);
        return Promise.reject(new Error(`Error occurred to get documents`)); //return the Promise which will be used by "co"
      });
        return Promise.resolve(docs); //return the Promise which will be used by "co"

      });  
  }
}; 

book.js

'use strict';
const dbcrud   = require("./crud");
const co = require("co");
module.exports = {

  getTransactions: (req, res) => {
   //use "co" to make asyn function call without callback
    co(function*() {
      let transactions = yield dbcrud.getTransactions('transactions');
      res.json(transactions);
    }).catch((err) => {
      console.error(`[ERROR:Controller:API:getTransactions]: error`, err);
      res.status(500);
      res.json({error: err.message});
    });
  },

};
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.