1
validateRegister: async (req, res, next) => {

        UserModel.findOne({email:req.body.email}, (err, example) => {
            console.log(example);
            if(err) console.log(err);
            if(example) {
                res.status(400).json({message: "Email already registered!"});
                res.end() //next('route')
            }
        });
        console.log("test");
        const user = new UserModel(req.body);
        await user.save((err) => {
            if (err) return res.status(500).json({ message: "Database issue!" });
        }); 

        next();
    },

Ok, I tried to insert user data if it is not already in the database using mongoose. If the User regarding the email is already in the database the response should be ended and the user not inserted. I tried to end the response with res.end() and next('route'), but nothing seems to work, the console.log("test") still runs.

Error:

events.js:353
      throw er; // Unhandled 'error' event
      ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:561:11)

Thanks for your help

Gamox
  • 13
  • 2

2 Answers2

2

Code below callback function gets executed before callback gets completed and multiple res.send happened.

you can try this

validateRegister: async (req, res, next) => {

UserModel.findOne({ email: req.body.email }, (err, example) => {
    console.log(example);
    if (err) {
        console.log(err);
        return res.status(500).json({ message: "Something went wrong" });

    }
    if (example) {
        return res.status(400).json({ message: "Email already registered!" });
    }
    console.log("test");
    const user = new UserModel(req.body);
    await user.save((err) => {
        if (err) return res.status(500).json({ message: "Database issue!" });
    });
});

next();
}

Or

validateRegister: async (req, res, next) => {
try {
    let example = await UserModel.findOne({ email: req.body.email });
    console.log(example);
    if (example)
        return res.status(400).json({ message: "Email already registered!" });
    console.log("test");
    const user = new UserModel(req.body);
    await user.save((err) => {
        if (err) return res.status(500).json({ message: "Database issue!" });
    });
    next();
} catch (err) {
    console.log(err);
    return res.status(500).json({ message: "Something went wrong" });
}
}
0

you can add return before returning response in the case of user email already found.

What seems to happen is that your program is calling res two times

Smriti Shikha
  • 421
  • 2
  • 6
  • So like ``` return res.status(400).json({message: "Email already registered!"}); ``` tried that before. You're right the program calls res.json two times, because the router is defined: ``` router.post("/api", middleware.validateRegister, (req, res, next) => { return res.status(201).json({ message: "Hello from server!" }); }); ``` I'm aware of that, but thats exactly the problem all the rest of the middleware code and the router code should be skipped if a user is already registered. – Gamox Dec 21 '21 at 16:48
  • it seems you are using validateRegister as a middleware . according to documentation (https://expressjs.com/en/guide/using-middleware.html) `app.get('/user/:id', function (req, res, next) { // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route') // otherwise pass the control to the next middleware function in this stack else next() }, function (req, res, next) { // send a regular response res.send('regular') })` you have to use next only – Smriti Shikha Dec 22 '21 at 05:57
  • if you want to throw error refer this (https://expressjs.com/en/guide/error-handling.html) – Smriti Shikha Dec 22 '21 at 06:00
  • Yeah exactly, I use it as Middleware. But I cannot write next() there to skip the rest of the code block and that would also just jump to the next middlware, which should not be triggered anyway. – Gamox Dec 22 '21 at 06:42