简体   繁体   中英

Node.js gives error: Can't set headers after they are sent

I am new to node.js and I am doing functionality of fetching all email address from Gmail. After getting responses I am sending responses into jade template. After getting single response I am getting en error in terminal:

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

My code is as below:

module.exports.getmailist =  function(req , res) {

    var google = require('googleapis');
    var gmail = google.gmail('v1');
    var email_list = Array();
    var myObject = Array();
    var accounting = [];
    var messageIds = [];
    var jsonString = false;
    var employees = {};
    var OAuth2 = google.auth.OAuth2;
    var oauth2Client = new OAuth2("--MY CLIENT ID--","SECRET ID","REDIRECT URL");
    oauth2Client.credentials = { access_token: req.session.access_token};

    var addData = function (req,response) {
        console.log(response);
        res.render('getmailist',{title: 'Product Template', result: response});
    }

    gmail.users.messages.list({ userId: 'me', 'q': "inbox", auth: oauth2Client}, function(err, response) {
        for(var i = 0; i< response.messages.length; i++) {
            //console.log(response.messages[i].id);
            gmail.users.messages.get({ userId: 'me', id:response.messages[i].id , auth: oauth2Client}, function(error , resp) {

            if(resp != "")
            {
                addData(req,resp)
            }
        });
    }

    return true;
    });
};

In console.log(response) , I get first datavalue of email as obejct and then below error is displayed.

Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:690:11)
at ServerResponse.header (/var/www/nodegoogle/node_modules/express/lib/response.js:700:10)
at ServerResponse.send (/var/www/nodegoogle/node_modules/express/lib/response.js:154:12)
at fn (/var/www/nodegoogle/node_modules/express/lib/response.js:934:10)
at View.exports.renderFile [as engine] (/var/www/nodegoogle/node_modules/jade/lib/index.js:374:12)
at View.render (/var/www/nodegoogle/node_modules/express/lib/view.js:93:8)
at EventEmitter.app.render (/var/www/nodegoogle/node_modules/express/lib/application.js:566:10)
at ServerResponse.res.render (/var/www/nodegoogle/node_modules/express/lib/response.js:938:7)
at addData (/var/www/nodegoogle/lib/callbacks/routes.js:63:11)
at /var/www/nodegoogle/lib/callbacks/routes.js:74:13

You're getting this error because the first step of your iteration that reaches addData(req,resp) is sending the response. Remember: the render method ends the response.

If you want to loop through response.messages array and perform an operation for each item before sending the response, you have to make sure to call addDate(req,res) only after the end of your loop.

Take a look at async.each from the async module. An example from the docs:

async.each(openFiles, function( file, callback) {

  // Perform operation on file here. 
  console.log('Processing file ' + file);

  if( file.length > 32 ) {
    console.log('This file name is too long');
    callback('File name too long');
  } else {
    // Do work to process file here 
    console.log('File processed');
    callback();
  }
  }, function(err){
    // if any of the file processing produced an error, err would equal that error 
    if( err ) {
      // One of the iterations produced an error. 
      // All processing will now stop. 
      console.log('A file failed to process');
    } else {
      console.log('All files have been processed successfully');
    }
});

So, in your scenario, you just have to do your stuff on each item (calling the local callback after each one, of course) and call your addData(req,resp) just at the last callback.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM