0

I am building a simple restful API using express4, mongoose and body parser as middleware.

Index.js

//base setup
var express = require('express'); // call express
var mailsystem = express(); // define our app using express
var bodyParser = require('body-parser');
var InDb = require('./mailsystem/client/clientsend');
var mangoose = require('mongoose');
var morgan = require('morgan');
mailsystem.use(morgan('dev'));
// require('daemon')();

mangoose.connect('mongodb://abc:abc@ds031982.mongolab.com:31982/mailsystem2');

// configure app to use bodyParser()
// this will let us get the data from a POST
mailsystem.use(bodyParser.urlencoded({
  extended: true
}));
mailsystem.use(bodyParser.json());

mailsystem.use(function(req, res, next) {
  req.rawBody = '';
  req.setEncoding('utf8');

  req.on('data', function(chunk) {
    req.rawBody += chunk;
  });

  req.on('end', function() {
    next();
  });
});

var port = process.env.PORT || 8080; // set our port

// ROUTES FOR OUR API
// =============================================================================
var router = express.Router(); // get an instance of the express Router

router.use(function(req, res, next) {
  console.log('inside route');
  next();
});
router.route('/clietsends')

.post(function(req, res, next) {


    //req.rawBody ='';
    //req.setEncoding('utf-8');
    // var mine;
    //var contentType = req.headers['content-type'] || '', mime = contentType.split(';')[0];


    var clientsend = new InDb();
    //clientsend.name = req.body.name;
    clientsend.emailId = req.body.emailId;
    clientsend.subject = req.body.subject;
    clientsend.message = req.body.message;
    var email = clientsend.emailId;
    var sub = clientsend.subject;
    var mess = clientsend.message;
    //Call_mandrill(email, sub, mess);
    console.log(req.body);
    console.log(req.params);
    clientsend.save(function(err) {
      if (err)
        res.send(err);
      else {
        req.body += req.rawBody;
        //req.rawBody += req.params;
        res.json(req.body);
        //console.log(req.params);
      }

      // res.json({message:'message of post created'})
    });
  })
  .get(function(req, res) {
    //need not to initiliaze again
    /*var clientsend = new InDb();
    clientsend.name = req.body.name;
    */
    InDb.find(function(err, clientsend) {
      if (err)
        res.send(err);

      res.json(clientsend);
    });
  });

router.route('/clietsends/:clietsend_id')
  .get(function(req, res) {

    InDb.findById(req.params.clietsend_id, function(err, clientsend) {
      if (err)
        res.send(err);
      res.json(clientsend);
    });
  })
  .put(function(req, res) {

    InDb.findById(req.params.clietsend_id, function(err, clientsend) {

      if (err)
        res.send(err);
      clientsend.emailId = req.body.emailId;
      clientsend.subject = req.body.subject;
      clientsend.message = req.body.message;

      // save the update 
      clientsend.save(function(err) {
        if (err)
          res.send(err);
        res.json(req.body);
        //res.json({ message: 'client updated!' });
      });

    });
  })

.delete(function(req, res) {
  InDb.remove({
    _id: req.params.clietside_id
  }, function(err, clientsend) {
    if (err)
      res.send(err);
    //var m = req.body;
    delete req.params.clietsend_id;
    console.log(req.params.clietsend_id);
    res.json({
      message: 'Successfully deleted'
    });
  });
});

// test route to make sure everything is working (accessed at GET http://localhost:8080/api)
router.get('/', function(req, res) {
  res.json({
    message: 'add /clietsends to view all'
  });
});

// more routes for our API will happen here

// REGISTER OUR ROUTES -------------------------------
// all of our routes will be prefixed with /api
mailsystem.use('/testapi', router);

// START THE SERVER
// =============================================================================
mailsystem.listen(port);
console.log('open port' + port);


//function mandrill
// =============================================================================
function Call_mandrill(email, sub, mess) {
  var mandrill = require('mandrill-api/mandrill.js');

  function log(obj) {
    //$('#response').text(JSON.stringify(obj));
    console.log(JSON.stringify(obj));
  }
  var m = new mandrill.Mandrill('9VUmdqbiZFiLCev4C_8Q6A');
  // LOOK HERE TO CHANGE FROM EMAIL ID
  //========================================
  var params = {
    "message": {
      "from_email": "noreply@signzy.com",
      "to": [{
        "email": email
      }],
      "subject": sub,
      "text": mess,
      "autotext": true,
      "track_opens": true,
      "track_links": true
    }
  };

  function sendTheMail() {

    m.messages.send(params, function(res) {
      log(res);
    }, function(err) {
      log(err);
    });
  }

  function run() {
    sendTheMail();
    return false;
  }
  run();

}

and clietsend.js in mailsystem/client/

// mailsystem/client/clientside.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var SendSchema = new Schema({
  emailId String, 
  subject String,
  message String 
});

module.exports = mongoose.model('Sent', SendSchema);

Everything works fine except I have 2 issues that I couldn't figure out:

1) the body/input is of the form xxx-urlencoded i want it to be in raw so went through this post and did changes to my code as you can see them in comments but they don't seem to work. What am I doing wrong? Can someone show an example?

2) The .delete function is returning the json object but not deleting it. Don't know why PUT, PUSH, GET seems to work fine though.

after jakerela suggestions made changes accordingly but the issue is on res.json(reqbody) a string is returned where i wanted a json object, and also somethig like "[object object]" is returned along

Community
  • 1
  • 1
hubatrix
  • 135
  • 1
  • 11

2 Answers2

0

It doesn't look like you actually followed the instructions in that other post. The body parser does not provide the raw body data at all, instead you have to implement that yourself using an Express middleware before your route and using Streams.

Add this code before your other routes (maybe line 19):

app.use(function(req, res, next) {
  req.rawBody = '';
  req.setEncoding('utf8');

  req.on('data', function(chunk) { 
    req.rawBody += chunk;
  });

  req.on('end', function() {
    next();
  });
});

The you can access req.rawBody from within your other routes.

Jordan Kasper
  • 13,153
  • 3
  • 36
  • 55
  • hey @jakerella thanks a lot i changed things as you said, but somehow i when do res.json(req.body) here i am getting a string and not a json object, before that line I added req.body += req.rawBody; what am I doing wrong ? I have updated the post with new code check it out please. – hubatrix Dec 24 '15 at 06:37
0

Well I figured it out, no need of any rawBody at all for the above code, just added content type in header and its working fine. as I was using postman just navigate to header and add the content type that should work. or you can also add a line in your code to make it work.

hubatrix
  • 135
  • 1
  • 11