0

I'm getting confused with next(); I read through this post which essentially says it passes control to the next route. In my code below, having next(); where it is causes me to get "Cannot set headers after they are sent to the client". However, if I comment that out and then restore the else clause of my if statement, it functions correctly both when an incorrect empID is passed as well as when a correct one is. I'm hoping someone could explain what exactly is happening? Why does the position of the next() matter? It seems like it would be called either way?

I'm trying to do what is happening in this post which is add a value to, say req.user, but I haven't been able to get that to work at all so I'm trying the method I have here.

let checkEmp = (req, res, next) => {
    db.get("select * from Employee where id = $id", {$id: req.empID},
        (err, row) => {
            if (err || row === undefined) {
                res.status(404).send();
            // } else {
            //     next();
            }
        });
    next();
};

// get all timesheets
timesheetRouter.get("/", getParams, checkEmp, (req, res, next) => {
    if (req.empID) {
        db.all("select * from Timesheet where employee_id = $id", {$id: req.empID},
            (err, rows) => {
                if (err) {
                    next(err);
                } else {
                    return res.status(200).send({timesheets: rows});
                }
            });
    } else {
        return res.status(404).send("Nothing to see here");
    }
});
Rafael
  • 7,605
  • 13
  • 31
  • 46
nathanjw
  • 832
  • 2
  • 13
  • 23
  • 1
    Which `next` are you talking about? – Chase Nov 01 '18 at 02:16
  • 1
    checkEmp is executed first - which sends response to client - followed by the main function which also sends response to client . - now if checkEmp sends the response then you cannot send a response again - as the connection to the client is closed - but your next function from checkEmp is the main function of your route tries to send the response again and fails with that error. – xan_z Nov 01 '18 at 02:16
  • 1
    Looks like `db.get()` is probably asynchronous, so in the example as shown, `next()` will be called before `db.get()` finishes and it moves on to the next handler. Then, when the `db.get()` finishes, it tries to send a response, but the response has already been sent by the anonymous function in the main handler. – Jim Perris Nov 01 '18 at 02:28
  • @Chase the `next()` on bottom line of checkEmp. – nathanjw Nov 01 '18 at 11:25
  • @JimPerris so by moving the `next()` inside of `db.get()` I'm essentially waiting for it to finish before moving on? – nathanjw Nov 01 '18 at 11:27
  • @nathanjw That's correct. – Jim Perris Nov 01 '18 at 15:05
  • @JimPerris can you move your comment into an answer so I can close the question? – nathanjw Nov 01 '18 at 16:51

1 Answers1

0

Looks like db.get() is probably asynchronous, so in the example as shown, next() will be called before db.get() finishes and it moves on to the next handler. Then, when the db.get() finishes, it tries to send a response, but the response has already been sent by the anonymous function in the main handler. By moving the next() inside of db.get(), you're essentially waiting for it to finish before moving on.

Jim Perris
  • 2,545
  • 1
  • 12
  • 15