-1

coders. I try to implement file upload through Multer. I however get an error trying to catch errors to send to the frontend. I've tried going through the documentation and the various questions already asked here on Stackoverflow but my understanding of English seems to be so low. Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client is my error. I can't find where the headers were sent, or where the process ended. May someone with a better understanding help me out. Here is my code. It happens after the db.query()

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, "./routes/files");
  },
  filename: (req, file, cb) => {
    cb(null, Date.now() + "-" + file.originalname);
  },
});

const upload = multer({ storage }).fields([
  { name: "file", maxCount: 1 },
  { name: "school_id", maxCount: 1 },
]);

router.post("/upload/students", (req, res) => {
  try {
    upload(req, res, (err) => {
      if (err) {
        console.log(err);
        res.json({ msg: err.message });
      } else {
        const filePath = req.files["file"][0].path; //req.file.path;
        const workbook = xlsx.readFile(filePath);
        const worksheet = workbook.Sheets[workbook.SheetNames[0]];

        const rows = xlsx.utils.sheet_to_json(worksheet);

        const school_id = req.body.school_id;
        console.log("SchoolId ", school_id);

        rows.forEach((row) => {
          const student_id = row.student_id;
          const klass_id = row.klass;
          const stream_id = row.stream;
          const name = row.name;
          const year = row.year;

          db.query(
            "INSERT INTO student(graduated, prefect, school_id,\
               name, student_id, klass_id, stream_id, year)\
            VALUES($1, $2, $3, $4, $5, $6, $7, $8 )",
            [0, 0, school_id, name, student_id, klass_id, stream_id, year],
            (err) => {
              if (err) {
                console.log(err);
                // res.json({ msg: err.message });
              } else {
                console.log("Successfull");
                // res.json({ success: "Students Uploaded Successfully" });
              }
            }
          );
        });
      }
    });
  } catch (err) {
    res.json({ msg: err.message });
  }
});

module.exports = router;
Phil
  • 157,677
  • 23
  • 242
  • 245
fakeMake
  • 738
  • 8
  • 18
  • 1
    This isn't very clear. Where is your _success_ response? You're also performing async operations in a loop. If you try and send a response within that loop (like with the commented-out code), it will cause the error you're seeing – Phil Apr 26 '23 at 06:55
  • 1
    Does this answer your question? [Error: Can't set headers after they are sent to the client](https://stackoverflow.com/questions/7042340/error-cant-set-headers-after-they-are-sent-to-the-client) – Phil Apr 26 '23 at 06:56

2 Answers2

0

Well you should wrap your async code inside a promise, then after promise you can res.send your success.

-1

An answer was posted that has since been deleted. Adding return solved it

if (err) {
    console.log(err);
    res.json({ msg: err.message });
    **return**
fakeMake
  • 738
  • 8
  • 18
  • 1
    There is no way, given the code in your question that this would solve the problem you describe – Phil Apr 26 '23 at 07:21
  • I realized that it's actually not yet working. But you're not providing a solution, why?? I'm using postgres – fakeMake Apr 26 '23 at 07:36
  • Why? Because I asked you a bunch of clarifying questions in the comments above and you haven't answered them or provided details – Phil Apr 26 '23 at 07:38
  • Success response is commented out, res.json({ success: "Students Uploaded Successfully" }); – fakeMake Apr 26 '23 at 07:40