0
votes

I'm new to mongoDB, Nodejs and express your helps would be more appreciated.

In below code i'm trying to find and get the remaining count from the collection model "examConfigModel" by passing the examcode, and there is check for remaining count if its greater the 0 then find another collection model "examRegisterModel" based on examcode and then there is a check to avoid duplicate entry to DB. If its unique then save the document else return error message "message:"Already Registered"". But after running the code the save is working fine but i'm getting below error and node server will stop.

Please help me how can i deal with multiple queries within a query.


Error: Can't set headers after they are sent. at validateHeader (_http_outgoing.js:491:11) at ServerResponse.setHeader (_http_outgoing.js:498:3) at ServerResponse.header (C:\practice\angular2\student-reg-app\node_modules\express\lib\response.js:767:10) at ServerResponse.send (C:\practice\angular2\student-reg-app\node_modules\express\lib\response.js:170:12) at ServerResponse.json (C:\practice\angular2\student-reg-app\node_modules\express\lib\response.js:267:15) at C:\practice\angular2\student-reg-app\server\routes\api.js:208:17 at C:\practice\angular2\student-reg-app\node_modules\mongoose\lib\model.js:4495:16 at model.$__save.error (C:\practice\angular2\student-reg-app\node_modules\mongoose\lib\model.js:396:7) at C:\practice\angular2\student-reg-app\node_modules\kareem\index.js:315:21 at next (C:\practice\angular2\student-reg-app\node_modules\kareem\index.js:209:27) at Kareem.execPost (C:\practice\angular2\student-reg-app\node_modules\kareem\index.js:217:3) at _cb (C:\practice\angular2\student-reg-app\node_modules\kareem\index.js:307:15) at $__handleSave (C:\practice\angular2\student-reg-app\node_modules\mongoose\lib\model.js:310:5) at C:\practice\angular2\student-reg-app\node_modules\mongoose\lib\model.js:193:7 at result (C:\practice\angular2\student-reg-app\node_modules\mongodb\lib\utils.js:414:17) at session.endSession (C:\practice\angular2\student-reg-app\node_modules\mongodb\lib\utils.js:401:11)

Below is the code please help me if not clear with my Question please let me know i will provide more details.

    const express = require('express');
    const router = express.Router();
    const mongoose = require('mongoose');
    const usersSchemaModel = require('../models/users-schema');
    const statesSchemaModel = require('../models/states-schema');
    const citiesSchemaModel = require('../models/cities-schema');
    const examSchemaModel = require('../models/exam-schema');
    const examConfigModel = require('../models/exam-config-schema');
    const examRegisterModel = require('../models/regrequests-schema');
    const db = require('../config/db');
    const bcrypt = require('bcryptjs');
    const passport = require('passport');
    const LocalStrategy = require('passport-local').Strategy;
    var jwt = require('jsonwebtoken');

    mongoose.Promise = global.Promise;
    mongoose.connect(db.database,(err)=>{
        if(err){
            res.json(err);
        }else{
            console.log('connected');
        }
    });

    //Register exam
    router.post('/exam/register',(req, res)=>{
        examConfigModel.findOne({
            examcode: req.body.exam
          },function(err, result) {
            if (err) {
                throw err;
            } else {
                console.log("Rem Seats: " + result.remaining);
                if(result.remaining > 0){
                    console.log("remaining: "+result.remaining);
                    const examModel = new examRegisterModel();
                    examModel.userid = req.body.userid;
                    examModel.stateid = req.body.stateid;
                    examModel.cityid = req.body.cityid;
                    examModel.exam_code = req.body.exam;
                    examModel.father_name = req.body.father_name;
                    examModel.last_name = req.body.last_name;
                    examModel.mobileno = req.body.mobileno;
                    examModel.city = req.body.city;
                    examModel.street = req.body.street;
                    examModel.address = req.body.address;
                    examModel.zipcode = req.body.zipcode;
                    console.log("RequestBody: "+req.body.exam);
                    examRegisterModel.findOne({
                        exam_code: req.body.exam
                      },function(err, resResult) {
                        if (err) {
                            throw err;
                        } else {
                            if(resResult == null){
                                save(examModel,result, res);
                            }else{
                            console.log("DB: "+ resResult +" REQ: "+ req.body.exam)
                            if(resResult.exam_code != req.body.exam){
                                console.log('notEqual')
                                save(examModel,result, res);
                            }else{
                                console.log()
                                res.json({reg:'failed',message:"Already Registered",errorCode:"6001"});
                            }
                        }
                        }
                      });
                }else{
                    res.json({reg:"failed",result:"No seat available",errorCode:7012});
                }
            }
          });
    });

    function save(examModel,result,res){

        examModel.save(function(err,config){
            if(err){
                console.log(err);
                res.json(err);
            }else{
                console.log(result);
                if(result != null){
                    const reduceCount = result.remaining-1;
                    res.json({reg:'success',rem:reduceCount,e_id:result._id,errorCode:""});
                }
                res.json({reg:'success',errorCode:""});
            }
        });
    }

    //Update Exam Config 
    router.put('/update/config/:id',(req, res)=>{
        examConfigModel.findByIdAndUpdate(req.params.id,{
            $set : {remaining:req.body.rem}
        },
        {
            new : true
        },
        function(err,updatedExamConfig){
            if(err){
                console.log(err);
                res.json(err);
            }else{
                res.json({config:'success'});
            }
        })
    });
1

1 Answers

0
votes

The reason why you are getting error Can't set headers after they are sent. is because your code has already send back response earlier and trying to send back another response. API has send back response to called, however function has not returned, so function continues till find a return statement or function meets an end that is closing braces.

Example with express.js:

router.post('/your/api', (req, res, next) => {
    //Do things here
    res.send('Sending response');  // response send

    // Doing more things, this is all right

    res.send('another response'); // Now error Can't set headers after they are sent.

   next();

}, (req, res) => {

    res.send('another response'); // Now error Can't set headers after they are sent.
});

res.send() send any kind of response and res.json() send only json response. Use any one again will get error Can't set headers after they are sent.

How to accidentally save from sending multiple response?

  1. Use if-else efficiently.
  2. Use only single res.send / res.json with dynamic statusCode res.status(statusCode).json(result).
  3. Always use return if nothing else is needed to be done once response is send. Example:

```

router.post('/your/api', (req, res, next) => {
    //Do things here
    return res.send('Sending response');  // response send, and function returned

    // Never came here.
    // Doing more things, this is all right

    return res.send('another response'); // Now error Can't set headers after they are sent.

   next();

 }, (req, res) => {

    // never came here as function already returned.
    return res.send('another response'); // Now error Can't set headers after they are sent.
});

```