Shaun
Shaun

Reputation: 1601

How can I use express router routes for dual use?

So I have a node app using express router and routes, for example I have a router that handles fetching company objects from the database, within the Company router the get method looks like this:

router.get('/:id', function(req, res, next) {
    var id = req.params.id;
    models.Company.get(Number(id), function(err, entity) {
        if (err) {
            console.error("Get error:", err);
        }
        console.log('Got entity:', entity);
        req.data = entity;
        next()
    });
});

Now if I am in another router, say the Reviews router and I want to get a company I would like to be able to call this route in order to grab that company, instead of having to duplicate code.

How do I do that?

Upvotes: 0

Views: 67

Answers (1)

rsp
rsp

Reputation: 111268

You can either use a named function, if you really want to use the same handler:

function yourHandler(req, res, next) {
    var id = req.params.id;
    models.Company.get(Number(id), function(err, entity) {
        if (err) {
            console.error("Get error:", err);
        }
        console.log('Got entity:', entity);
        req.data = entity;
        next()
    });
}
router.get('/:id', yourHandler);
router2.get('/companies/:id', yourHandler);

Or you can abstract away only the actual database lookup, by making a function that takes a callback:

function getCompany(id, callback) {
    models.Company.get(Number(id), function(err, entity) {
        if (err) {
            console.error("Get error:", err);
            callback(err);
        } else {
            console.log('Got entity:', entity);
            callback(null, entity);
        }
    });
}

or a function that returns a promise:

function getCompany(id) {
    return new Promise(function (resolve, reject) {
        models.Company.get(Number(id), function(err, entity) {
            if (err) {
                console.error("Get error:", err);
                reject(err);
            } else {
                console.log('Got entity:', entity);
                resolve(entity);
            }
        });
    });
}

The difference is that you use the callback-taking version like this:

getCompany(123, function (err, data) {
  if (err) {
    // handle error
  } else {
    // you have data
  }
});

and you use the promise-returning version like this:

getCompany(123)
.then(function (data) {      
  // you have data
})
.catch(function (err) {
  // handle error
});

The callback versions are easy to compose using the async module and the promise versions are easy to compose using the bluebird module or some other promise framework. See:

It's also worth mentioning that Bluebird is much faster than native ES6 promises, see this answer for details.

Upvotes: 2

Related Questions