1

I had tried set the header, but it does not work. I put return at the end of every lines already. Therefore it should not execute res.json(data) twice.

Please correct me if I am wrong.

app.js

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');
//var users = require('./routes/users');
var api = require('./routes/api');
var users_page = require('./routes/users_page');
var quizzes = require('./routes/quizzes');
var subjects = require('./routes/subjects');
var questions = require('./routes/questions');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
//app.use('/users', users);
app.use('/api', api);
app.use('/users',users_page);
app.use('/quizzes', quizzes);
app.use('/subjects',subjects);
app.use('/questions',questions);


// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});


module.exports = app;

users_page.js

var express = require('express');
var router = express.Router();
var pg = require('pg');
var connectionString = process.env.DATABASE_URL || 'postgres://admin:admin@localhost:5432/mydb';

var userHandler = require('./userHandler_post.js'); 
router.post('/', userHandler.post);

var usr2 = require('./userHandler_getusrinfo.js');
router.get('/:username', usr2.getusrinfo);

var usr3 = require('./userHandler_upusr.js');
router.put('/:username', usr3.upusr);


var usr4 = require('./userHandler_del.js');
router.delete('/:username', usr4.del);


var usr5 = require('./userHandler_repasswd.js');
router.put('/reset_password/:username', usr5.repasswd);


var usr6 = require('./userHandler_getall.js');
router.get('/', usr6.get);

module.exports = router;

userHandler_getusrinfo.js :

var pg = require('pg');
var connectionString = process.env.DATABASE_URL || 'postgres://admin:admin@localhost:5432/mydb';

exports.getusrinfo = function(req, res, callback) {

    var username = req.params.username;

  pg.connect(connectionString, function(err, client, done) {
    // Handle Errors
    if(err) {
        res.setHeader('Content-Type', 'application/json');
      res.json(err);
      return ;
    }

        var q2 = client.query("SELECT * FROM dugong.users WHERE UserName =$1 ;",[username]);

        q2.on('error', function(error) {
            var data = {success : false, 
                                    username : username,
                                    reason : {errmsg : error.detail,
                                                        errid : error.code} };  
            res.setHeader('Content-Type', 'application/json');
            res.json(data);
            return callback();
        });    

      q2.on('row', function(row, result) {
          result.addRow(row);
          return ;
      });

      q2.on('end', function(result) {

          if (result.rowCount == 0) {
                    var data = {success : false, 
                                            username : username, 
                                            reason : {errmsg : "Username not found", 
                                                                errid : 'q2'}};
                    res.setHeader('Content-Type', 'application/json');
                    res.json(data);

                    return callback();
                }

                var sumdata = {success: true,
                                        username : result.rows[0].username,
                                        ... //omit to keep it short
                                        FaxNumber : result.rows[0].faxnum
                                        };
          res.setHeader('Content-Type', 'application/json');
          res.json(sumdata);
          return callback();
      });
      done();
      return ;
  });
  pg.end();
};

However, I got the annoying message like this. But program runs fine!

GET /users/Sari 500 45.026 ms - 89
Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
    at ServerResponse.header (/home/sarit/4alls/mariner/node_modules/express/lib/response.js:700:10)
    at ServerResponse.send (/home/sarit/4alls/mariner/node_modules/express/lib/response.js:154:12)
    at fn (/home/sarit/4alls/mariner/node_modules/express/lib/response.js:934:10)
    at View.exports.renderFile [as engine] (/home/sarit/4alls/mariner/node_modules/jade/lib/index.js:374:12)
    at View.render (/home/sarit/4alls/mariner/node_modules/express/lib/view.js:93:8)
    at EventEmitter.app.render (/home/sarit/4alls/mariner/node_modules/express/lib/application.js:566:10)
    at ServerResponse.res.render (/home/sarit/4alls/mariner/node_modules/express/lib/response.js:938:7)
    at /home/sarit/4alls/mariner/app.js:64:7
    at Layer.handle_error (/home/sarit/4alls/mariner/node_modules/express/lib/router/layer.js:58:5)

Do I need to touch app.js:64:7 which is made by Express? If so, how can I do it in proper way?

halfer
  • 19,824
  • 17
  • 99
  • 186
joe
  • 8,383
  • 13
  • 61
  • 109
  • Could you share your App.js file? Your error looks like it's coming from rendering a view. Maybe you're sending your JSON data and then trying to render and return a view? – Chris Anderson Jul 06 '15 at 08:08
  • http://stackoverflow.com/questions/7042340/node-js-error-cant-set-headers-after-they-are-sent?rq=1 could be useful – Yann Bertrand Jul 06 '15 at 08:30
  • @ChrisAnderson-MSFT I just update my question. – joe Jul 06 '15 at 08:37
  • @YannBertrand . I have read it. That is why I put res.setHeader() over res.json. I am still finding the root cause of it. – joe Jul 06 '15 at 08:40
  • You're using `res.json` and calling `callback`, which is passing to the error handler. – Ben Fortune Jul 06 '15 at 10:06

2 Answers2

1

You shouldn't be calling the callback (next) function if there isn't more work to be done or an error. You have a catchall in your App.js file (I'm assuming because you didn't post it), which is being hit because you called the callback (next) function. It's trying to render an error page, hence the call to Jade rendering.

Remove the callback calls.

Chris Anderson
  • 8,305
  • 2
  • 29
  • 37
  • Hi. I need callback since I am now creating an unit test. Therefore I create a checking function first to solve my problem. Thank you :) – joe Jul 07 '15 at 01:38
-1

put your q2 query code in else part.

KlwntSingh
  • 1,084
  • 8
  • 26
  • @Kulwant . still same error and program run like no else{} – joe Jul 06 '15 at 09:07
  • @Jan Any information do you need. I will provide you as fast as I can. – joe Jul 06 '15 at 09:07
  • @Sarit I haven't met node.js closely yet so I am not capable of answering your question. I just like short answers to long questions. – Jan Turoň Jul 06 '15 at 09:16
  • @sarit i think here callback is acting as next so you next is being called. – KlwntSingh Jul 06 '15 at 09:21
  • @user111111111. I had accepted you answer, but my reputation is not over 15 yet. Very strange I had posted my comment already since Jul 7, but it gone. – joe Jul 12 '15 at 07:42