0

Im working on a University project for a Economical Department. I have many routes working correctly, but only this one creating a massive problem for me.

Whenever this route is done and the response is sent, I get the following error:

Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:346:11)
at ServerResponse.header (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/express/lib/response.js:719:10)
at ServerResponse.send (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/express/lib/response.js:164:12)
at ServerResponse.json (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/express/lib/response.js:250:15)
at /Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/controllers/application.js:171:56
at Query._callback (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/models/application.js:141:25)
at Query.Sequence.end (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/mysql/lib/protocol/sequences/Sequence.js:85:24)
at Query._handleFinalResultPacket (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/mysql/lib/protocol/sequences/Query.js:144:8)
at Query.OkPacket (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/mysql/lib/protocol/sequences/Query.js:78:10)
at Protocol._parsePacket (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/mysql/lib/protocol/Protocol.js:280:23)

The following is the function called by this route:

registerFactory: function (req, res ) {
        var userDetails = req.user;
        var requestData = req.body;
        var hscode = "NULL";
        var applicationID = "FR";
        var applicationType = "Factory";
        var factoryId = "";
        if (userDetails.usergroup == "Client") {
            var d = new Date();
            var year = d.getFullYear();
            applicationID = applicationID + year;
            var dnum = 5;
            var num = 0;
            applicationModel.getLastAppID(applicationType, function (err, results) {
                if (err) {
                    return res.json({success: false, message: 'Database Error. '});
                }else{
                    num = results[0].LastID;
                    console.log(num);
                    dnum = dnum - num.toString().length;
                    while (dnum != 0) {
                        applicationID = applicationID + "0";
                        dnum = dnum - 1;
                    }
                    applicationID = applicationID + num;
                    num = num + 1;
                    applicationModel.updateLastAppID(num, applicationType, function (err) {
                        if (err) {
                            return res.json({success: false, message: 'Database Error. '});
                        }else{
                            factoryController.registerFactory(userDetails,requestData, function (err,FID) {
                                if (err) {
                                    return res.json({success: false, message: 'Database Error. '});
                                }else{
                                    factoryId =  FID;
                                    applicationModel.createFactoryRegApplication(userDetails, requestData, applicationType, applicationID,hscode, function (err) {
                                        if (err) {
                                            return res.json({success: false, message: 'Database Error. '});
                                        } else {
                                            res.json({
                                                success: true,
                                                message: 'Application Created',
                                                data: {RequestID: applicationID,
                                                    FactoryID : factoryId
                                                }
                                            });
                                        }
                                    });
                                }
                            });

                        }
                    });
                }
            });
        } else {
            return res.json({success: false, message: 'unauthorized Access'});
        }
    }

I have no Idea why this is happening, even though res.json is never called twice.

1 Answers1

3

A code like this is extremely hard to maintain:

http://icompile.eladkarako.com/wp-content/uploads/2016/01/icompile.eladkarako.com_callback_hell.gif

It doesn't even fit on the screen here so I'm having a hard time reading it. I can give you some general advice on how to refactor it so it is manageable. Hopefully this will help you fix this problem and also similar problems in the future.

First, take every single anonymous function and change it to a named function. So, when you have:

applicationModel.updateLastAppID(num, applicationType, function (err) {
  // ...
});

Change it to:

applicationModel.updateLastAppID(num, applicationType, updatedLastAppID);

function updatedLastAppID(err) {
  // ...
}

Do it with every function that you have. This alone will probably show you your problem because you will have a nice self-documented code that is easy to read and understand, because:

  • The functions will be named and also the errors will be easier to read
  • Nothing will get indented so far that it's out of the screen
  • You will be able to see at one function at a time

For example this:

                applicationModel.updateLastAppID(num, applicationType, function (err) {
                    if (err) {
                        return res.json({success: false, message: 'Database Error. '});
                    }else{
                        factoryController.registerFactory(userDetails,requestData, function (err,FID) {
                            if (err) {
                                return res.json({success: false, message: 'Database Error. '});
                            }else{
                                factoryId =  FID;
                                applicationModel.createFactoryRegApplication(userDetails, requestData, applicationType, applicationID,hscode, function (err) {
                                    if (err) {
                                        return res.json({success: false, message: 'Database Error. '});
                                    } else {
                                        res.json({
                                            success: true,
                                            message: 'Application Created',
                                            data: {RequestID: applicationID,
                                                FactoryID : factoryId
                                            }
                                        });
                                    }
                                });
                            }
                        });
                    }
                });

will change to this:

applicationModel.updateLastAppID(num, applicationType, updatedID);

function updatedID(err) {
  if (err) {
    return res.json({success: false, message: 'Database Error. '});
  } else {
    factoryController.registerFactory(userDetails, requestData, factoryRegistered);
  }
}
// etc.

This is a first step but without it you will have a really hard time making sure that it all works.

This is not hard, you can do it yourself step by step. If you don't see the problem right away then you can post another question but with a code that is readable you will be much more likely to get answers.

rsp
  • 107,747
  • 29
  • 201
  • 177