Michael Michael - 1 month ago 6
Node.js Question

Can't use Express to send data back to client more than once

In my app, I send a post request to the server with data containing a CSV file:

$.ajax({
type:"POST",
contentType: "application/json",
url:"/",
data: JSON.stringify({fileData:My_CSV_FILE}),
success: function(csvJson) {
console.log('in the done block!');
//can use csvJson in this handler
});
});


Note: I'm posting to the home route, and I am able to get a response with the data converted from the server. The problem is that whether I run on localhost or Heroku, I am only able to trigger the POST request once, then I have to restart the server (even if I refresh the page). So I know the issue is with my route somewhere:

UPDATED TO INCLUDE FULL SERVER FILE:

'use strict';
const express = require('express');
const csvtojson = require('csvtojson');
const PORT = process.env.PORT || 3000;
const bodyParser = require('body-parser');
const Converter = require('csvtojson').Converter;

var converter = new Converter({});
let app = express();

app.use(bodyParser.json({limit: '300kb'}));

app.use(express.static(__dirname +'/public'));

app.post('/',function(req,res) {
var csvFile = (req.body.fileData);
converter.fromString(csvFile, function(err, result) {
if(!err) {
console.log(result);
res.json(result);
}else {
res.json({error: 'Could not convert'});
}
})
});

app.listen(PORT, () => {
console.log(`app listening on port ${PORT}`);
});


I'm using Express 4. Again, everything works, but only once. When I run Heroku logs, or check the console on localhost I get:

Error: Can't set headers after they are sent.


But I don't understand how I'm re-setting them.
If wanting to run on localhost, here is a link to the projects github: https://github.com/qctimes/calendar_export

Answer

You should move the converter instantiation to be done inside the app.post callback method. This way it will instantiate a new object at every request.

This is is how your code should be:

'use strict';
const express = require('express');
const csvtojson = require('csvtojson');
const PORT = process.env.PORT || 3000;
const bodyParser = require('body-parser');
const Converter = require('csvtojson').Converter;

let app = express();

app.use(bodyParser.json({limit: '300kb'}));

app.use(express.static(__dirname +'/public'));

app.post('/',function(req,res) {
  var csvFile = (req.body.fileData);
  var converter = new Converter({}); // instantiation is done here
  converter.fromString(csvFile, function(err, result) {   

    if(!err) {
      console.log(result);
      res.send(result);
    }else {
      res.send({error: 'Could not convert'});
    }
  });
});

app.listen(PORT, () => {
  console.log(`app listening on port ${PORT}`);
});
Comments