Define/Use a promise in Express POST route on node.js

229
February 22, 2017, at 8:53 PM

I currently have a POST route defined in an Express Node.js application as so:

var locationService = require("../app/modules/locationservice.js");
app.post('/createstop', isLoggedIn, function(req, res) {
    locationService.createStop(res, req.body);
});

(for this question, please assume the routing in & db works.. my record is created on form submission, it's the response I am struggling with)

In the locationservice.js class I then currently have

var models  = require('../models');
exports.createStop = function(res, formData) {
    models.location.build({ name: formData.name })
                   .save()
                   .then(function(locationObj) {
                             res.json({ dbResult : locationObj });
                         });
};

So as you can see, my route invokes the exported function CreateStop which uses the Sequelize persistent layer to insert a record asynchronously, after which I can stick the result on the response in the promised then()

So at the moment this only works by passing the response object into the locationservice.js method and then setting res.json in the then() there. This is sub-optimal to me with regards to my service classes, and doesn't feel right either.

What I would like to be able to do is "treat" my createStop method as a promise/with a callback so I can just return the new location object (or an error) and deal with it in the calling method - as future uses of this method might have a response context/parameter to pass in/be populated.

Therefore in the route I would do something more like:

var locationService = require("../app/modules/locationservice.js");
app.post('/createstop', isLoggedIn, function(req, res) {
    locationService.createStop(req.body)
        .then(dataBack) {
            res.json(dataBack); 
        };
});

Which means, I could call createStop from else where in the future and react to the response in that promise handler. But this is currently beyond me. I have done my due diligence research, but some individual expert input on my specific case would be most appreciated.

Answer 1

Your locationservice.js could look like that

exports.createShop = function(data){
    // here I have used create instead of build -> save
    return models.location.create(data).then(function(location){
        // here you return instance of saved location
        return location;
    });
}

And then your post() method should be like below

app.post('/createstop', isLoggedIn, function(req, res){
    locationService.createShop(req.body).then(function(location){
        // here you access the location created and saved in createShop function
        res.json(location);
    }).catch(function(error){
        // handle the error
    });
});
Answer 2

Wrap your createStop function with a promise like so:

exports.createStop = function(res, formData) {
    return new Promise(function(resolve, reject) {
        models.location.build({ name: formData.name })
                   .save()
                   .then(function(locationObj) {
                             resolve({ dbResult : locationObj });
                   });
                   //in case of error, call reject();
    });
};

This will allow you to use the .then after the createStop within your router.

READ ALSO
How to implement direct message stream using Twitter API in node js?

How to implement direct message stream using Twitter API in node js?

I have tried twitter documentation but it does not specify its implementationI have used package 'twitter' for streaming

270
Nodejs Chat with express, socket.io , mongodb and front end AngularJS

Nodejs Chat with express, socket.io , mongodb and front end AngularJS

I would like to build a chat application using nodejs and socketio

330
Jade in Express JS is not Rendering

Jade in Express JS is not Rendering

I am excepting a username from a from with input(name="name")

307