'Why I am getting this error "Cannot set headers after they are sent to the client" ? - Node.js

I'm just starting with node.js and I'm encountering some troubles with the CRUD particularly with the PUT method to update the data in MongoDb.

In my terminal I've got the error appears with :

  • in the update function,

  • in the follow function

    node:events:368 throw er; // Unhandled 'error' event ^

    Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client at new NodeError (node:internal/errors:371:5) at ServerResponse.setHeader (node:_http_outgoing:576:11) at ServerResponse.header (/Documents/BookFace/server/node_modules/express/lib/response.js:776:10) at ServerResponse.send (/Documents/BookFace/server/node_modules/express/lib/response.js:170:12) at ServerResponse.json (/Documents/BookFace/server/node_modules/express/lib/response.js:267:15) at /Documents/BookFace/server/controllers/user.controller.js:75:37 at /Documents/BookFace/server/node_modules/mongoose/lib/model.js:4961:18 at processTicksAndRejections (node:internal/process/task_queues:78:11) Emitted 'error' event on Function instance at: at /Documents/BookFace/server/node_modules/mongoose/lib/model.js:4963:15 at processTicksAndRejections (node:internal/process/task_queues:78:11) { code: 'ERR_HTTP_HEADERS_SENT' }

Here is the code :

const UserModel = require('../models/user.model')
const ObjectID = require('mongoose').Types.ObjectId

module.exports.getAllUsers = async (req, res) => {
    //send all details about all users except the password
    const users = await UserModel.find().select('-password') 
    res.status(200).json(users)
}

module.exports.userInfo = (req, res) => {
    //params = the param which is written into the url
    /* console.log(req.params) */
    if (!ObjectID.isValid(req.params.id))
    return res.status(400).send('Id unknown : ' + req.params.id)

    UserModel.findById(req.params.id, (err, docs) => {
        if (!err) res.send(docs)
        else console.log('ID unknown : ' + err)
    }).select('-password')
}

module.exports.updateUser = async (req, res) => {
    if (!ObjectID.isValid(req.params.id))
      return res.status(400).send("ID unknown : " + req.params.id);
  
    try {
      await UserModel.findOneAndUpdate(
        { _id: req.params.id },
        {
          $set: {
            bio: req.body.bio,
          },
        },
        { new: true, upsert: true, setDefaultsOnInsert: true },
        (err, docs) => {
          if (!err) return res.send(docs);
          if (err) return res.status(500).send({ message: err });
        }
      );
    } catch (err) {
      return res.status(500).json({ message: err });
    }
  }

  module.exports.deleteUser = async (req, res) => {
    if (!ObjectID.isValid(req.params.id))
    return res.status(400).send("ID unknown : " + req.params.id);

    try {
        await UserModel.deleteOne({ _id: req.params.id }).exec()
        res.status(200).json( { message: 'succefully deleted.'})
    }

    catch(err){
        return res.status(500).json({message: err})
    }
  }

  module.exports.follow = async (req, res) => {
    if (
      !ObjectID.isValid(req.params.id) ||
      !ObjectID.isValid(req.body.idToFollow)
    )
      return res.status(400).send("ID unknown : " + req.params.id);
  
    try {
      // add to the follower list
      await UserModel.findByIdAndUpdate(
        //id of the user
        req.params.id,
        //id of the user to follow
        { $addToSet: { following: req.body.idToFollow } },
        { new: true, upsert: true },
        (err, docs) => {
          if (!err) res.status(201).json(docs);
          else return res.status(400).json(err);
        }
      );
      //add to following list of the user followed
      await UserModel.findByIdAndUpdate(
        req.body.idToFollow,
        { $addToSet: { followers: req.params.id } },
        { new: true, upsert: true },
        (err, docs) => {
          // if (!err) res.status(201).json(docs);
          if (err) return res.status(400).json(err);
        }
      );
    } catch (err) {
      return res.status(500).json({ message: err });
    }
  };


Solution 1:[1]

module.exports.follow = async (req,res) => {
    if (!ObjectID.isValid(req.params.id) || !ObjectID.isValid(req.body.idToFollow))
    return res.status(400).send('ID unknown : ' + req.params.id);
try {
    // add to the follower list
    await UserModel.findByIdAndUpdate(
        req.params.id,
        {$addToSet: {following: req.body.idToFollow}},
        {new:true,upsert:true})
        
        //(err,docs)=> {
           // if (!err) res.status(201).json(docs);
            //else return res.status(400).json(err);
        //}

    .then((docs) => res.send(docs))
    .catch((err) => res.status(500).send({message:err}));
    // add to following list
    await UserModel.findByIdAndUpdate(
        req.body.idToFollow,
        {$addToSet: {followers: req.params.id}},
        {new:true,upsert:true})
        .catch((err) => res.status(500).send({message:err}));
} catch(err) {
    return res.status(500).json({message:err});
}
};

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Adama TRAORÉ