0

I am trying to send number over to the server with JQuery on the client side and received with NOde.JS and ExpresJS on the server side.

Here's the client code:

var value = $(object.selectId()).val();
    alert("Uploading " + value);
    $.ajax({
        type: 'POST',
        data: JSON.stringify({
            num : value
        }),
        contentType: 'application/json',
        url: '/testData',
        success: function (data) {
            alert('Successfully uploaded : ' + value + " and received " + JSON.parse(data).num);
        }
    }

Here's the server code:

app.post('/testData', function (req, res) {
var x1 = req.num
console.log("Got number : " + x1);
var x = JSON.stringify({
    num: (x1)
});
res.send(x);});

The server receives "undefined" and so does the client receive back.

EternallyCurious
  • 2,345
  • 7
  • 47
  • 78

2 Answers2

2

Can you try logging req.body on the server side(console.log(req.body);? The variable num will be available as req.body.num instead of req.num.

vmx
  • 7,989
  • 4
  • 22
  • 20
  • 1
    Also, make sure you're using `app.use(express.bodyParser());` Otherwise the req.body variable will not be populated. – Timothy Strimple Dec 04 '13 at 06:41
  • 1
    If you not using file uploads, you should just do `app.use(express.json()` to support json posts, and `app.use(express.urlencoded())` to support normal form posts. In case you're using file uploads, use `formidable` instead -- avoid using `app.use(express.bodyParser())`. – vmx Dec 04 '13 at 06:51
  • Thans for that comment. I am using file uploads/downloads, and I installed "formidable" as you suggested. Are there any code samples of how you can upload files with jQuery on the client and formidable on the server. I want to be able to save the file on the server's filesystem – EternallyCurious Dec 04 '13 at 09:41
  • This qualifies as separate question on its own. You can google around for working with formidable. I will share some code snippet as another answer shortly. – vmx Dec 04 '13 at 10:16
1

Instead of express.bodyParser() or express.multipart() middlewares, you should use formidable or any other module to parse incoming form.

I'm sharing some code snippet to get ajax based file upload working, using formidable on the server side. We will also need jQuery Form Plugin.

Create a sample html form;

<form id="fileUploadForm" accept-charset="utf-8" method="post", action="/upload" enctype="multipart/form-data">
  <input type="file" name="userfile" multiple="multiple" />
  <button type="submit"> Upload </button>
</form>

Add some client side javascript to handle ajax uplaods. Assuming you've jQuery and jQuery form js loaded.

var $form = $("#fileUploadForm");
$form.submit(function (e) {
  // perform client side validations if any

  $(this).ajaxSubmit({
    error: function () {
      // handle error
    },

    success: function (response) {
      // handle success
    }
  });

  // Important: stop event propagation
  return false;
});

On serverside, add a file upload post route.

var upload = require('./upload');

app.post('/upload', upload.parse, upload.save, upload.respond, upload.errors);

Create upload.js to handle file uploads.

var fs = require('fs');
var util = require('util');
var path = require('path');
var formidable = require('formidable');

var upload = {

  parse: function parse(req, res, next) {
    var form = new formidable.IncomingForm();
    form.encoding = 'utf-8';
    form.uploadDir = process.env.TMP || process.env.TMPDIR || process.env.TEMP || '/tmp' || process.cwd();
    form.keepExtensions = true;
    form.type = 'multipart';

    form.parse(req, function (err, fields, files) {
      req.files = files;
      next(err);
    });
  },

  save: function save(req, res, next) {
    // validate if upload was successful
    if (!req.files || !req.files.userfile) return next(new Error('Upload data not received, can\'t proceed.'));

    var userfile = req.files.userfile;
    // examine this object for available attributes
    console.log(userfile);

    // ensure public/data dir exists
    var dataDir = 'public/data';
    var target = path.join(dataDir, userfile.name);

    fs.rename(userfile.path, target, function (err) {
      req.uploadLink = target.replace(/public/gi, '');
      next(err);

      // cleanup
      fs.unlink(userfile.path, function () {});
    });
  },

  respond: function respond(req, res, next) {
    var response = {
      result: 'success',
      upload: req.uploadLink,
      message: 'File uploaded!'
    };
    res.status(200).json(response);
  },

  errors: function errors(err, req, res, next) {
    console.log(err);
    var response = {
      status: 'failure',
      message: 'File upload failed!'
    };
    res.status(400).json(response);
  }
};

module.exports = upload;

Hope this helps, you can update the code to suit your needs. Let me know if need any clarification.

Good day!

vmx
  • 7,989
  • 4
  • 22
  • 20
  • Hi! The jQuery code you've provided does not work. $(this).ajaxsubmit throws an error. Are you sure this is precisely correct? My javascript code is actually written in TypeScript which throws an error. The TS compiler says: error TS2094: The property 'ajaxSubmit' does not exist on value of type 'JQuery' – EternallyCurious Dec 06 '13 at 04:16
  • You need to include [jquery form plugin](http://malsup.com/jquery/form/#download) along with jquery script. I have included link to download the script in the answer. – vmx Dec 06 '13 at 04:35
  • Thanks, but since my code is in TypeScript, I'm hoping to get a .d.ts file instead, instead of a .js file. Do you know, if there is a d.ts available for this plugin or how to convert it into one. I cant find an automated way to converting it to typescript. – EternallyCurious Dec 06 '13 at 05:05
  • Haven't worked with typescript yet, can you rename `.js` to a `.ts` and try. Check these out: http://stackoverflow.com/a/14413739/1520518 and http://stackoverflow.com/a/12722003/1520518 – vmx Dec 06 '13 at 05:14
  • I've converted the code to typescript .d.ts, but this problem persists. Webstorm can't recognize $(this) sign. Are you sure the code you've pasted is syntactically right? Specifically, it says "Argument types do not match parameters" – EternallyCurious Dec 06 '13 at 12:47
  • I'm not using typescript, but the code above works fine for me. Can you replace `$(this).ajaxSubmit..` with `$form.ajaxSubmit` and see if it works? – vmx Dec 06 '13 at 13:08
  • Thanks. This problem is solved. Although the upload is still not working. I've posted another question here: http://stackoverflow.com/questions/20426317/file-not-uploading-with-jquery-expressjs – EternallyCurious Dec 06 '13 at 14:30