Error Handling mongoose with forEach loop












1














I have a mongodb with express and I'm getting Cannot set headers after they are sent to the client. Unhandled promise rejections are deprecated error when doing the following.



exports.deleteBooking = (req, res, next) => {
req.body.courts.forEach(element => {
Booking.deleteOne({$and: [
{ cid: element.cid },
{ year: element.day.year }
]})
.then(result => {
res.status(201).json({
message: result
});
})
.catch(() => {
res.status(500).json({
error: 'error'
})
});
})
};


I am sending an array of objects to my server and want to perform one deletion per object.



Because of the forEach it might run the .catch after the headers are sent to the client. What is the correct way of handling .then and .catch with a forEach loop?



Thank you!



EDIT: I forgot to add that if I would delete the .then and .catch the query would still run, and without errors. But I would like to keep the error handling in this case.










share|improve this question






















  • Should the response, whether it is error or message be send after the entire forEach loop is done or for each item in the loop?
    – Jeevan
    Nov 22 at 14:57










  • So I tried this but then it gives the error Cannot read property 'then' of undefined
    – Devchris
    Nov 22 at 15:17
















1














I have a mongodb with express and I'm getting Cannot set headers after they are sent to the client. Unhandled promise rejections are deprecated error when doing the following.



exports.deleteBooking = (req, res, next) => {
req.body.courts.forEach(element => {
Booking.deleteOne({$and: [
{ cid: element.cid },
{ year: element.day.year }
]})
.then(result => {
res.status(201).json({
message: result
});
})
.catch(() => {
res.status(500).json({
error: 'error'
})
});
})
};


I am sending an array of objects to my server and want to perform one deletion per object.



Because of the forEach it might run the .catch after the headers are sent to the client. What is the correct way of handling .then and .catch with a forEach loop?



Thank you!



EDIT: I forgot to add that if I would delete the .then and .catch the query would still run, and without errors. But I would like to keep the error handling in this case.










share|improve this question






















  • Should the response, whether it is error or message be send after the entire forEach loop is done or for each item in the loop?
    – Jeevan
    Nov 22 at 14:57










  • So I tried this but then it gives the error Cannot read property 'then' of undefined
    – Devchris
    Nov 22 at 15:17














1












1








1







I have a mongodb with express and I'm getting Cannot set headers after they are sent to the client. Unhandled promise rejections are deprecated error when doing the following.



exports.deleteBooking = (req, res, next) => {
req.body.courts.forEach(element => {
Booking.deleteOne({$and: [
{ cid: element.cid },
{ year: element.day.year }
]})
.then(result => {
res.status(201).json({
message: result
});
})
.catch(() => {
res.status(500).json({
error: 'error'
})
});
})
};


I am sending an array of objects to my server and want to perform one deletion per object.



Because of the forEach it might run the .catch after the headers are sent to the client. What is the correct way of handling .then and .catch with a forEach loop?



Thank you!



EDIT: I forgot to add that if I would delete the .then and .catch the query would still run, and without errors. But I would like to keep the error handling in this case.










share|improve this question













I have a mongodb with express and I'm getting Cannot set headers after they are sent to the client. Unhandled promise rejections are deprecated error when doing the following.



exports.deleteBooking = (req, res, next) => {
req.body.courts.forEach(element => {
Booking.deleteOne({$and: [
{ cid: element.cid },
{ year: element.day.year }
]})
.then(result => {
res.status(201).json({
message: result
});
})
.catch(() => {
res.status(500).json({
error: 'error'
})
});
})
};


I am sending an array of objects to my server and want to perform one deletion per object.



Because of the forEach it might run the .catch after the headers are sent to the client. What is the correct way of handling .then and .catch with a forEach loop?



Thank you!



EDIT: I forgot to add that if I would delete the .then and .catch the query would still run, and without errors. But I would like to keep the error handling in this case.







node.js mongodb mongodb-query






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 22 at 14:27









Devchris

102




102












  • Should the response, whether it is error or message be send after the entire forEach loop is done or for each item in the loop?
    – Jeevan
    Nov 22 at 14:57










  • So I tried this but then it gives the error Cannot read property 'then' of undefined
    – Devchris
    Nov 22 at 15:17


















  • Should the response, whether it is error or message be send after the entire forEach loop is done or for each item in the loop?
    – Jeevan
    Nov 22 at 14:57










  • So I tried this but then it gives the error Cannot read property 'then' of undefined
    – Devchris
    Nov 22 at 15:17
















Should the response, whether it is error or message be send after the entire forEach loop is done or for each item in the loop?
– Jeevan
Nov 22 at 14:57




Should the response, whether it is error or message be send after the entire forEach loop is done or for each item in the loop?
– Jeevan
Nov 22 at 14:57












So I tried this but then it gives the error Cannot read property 'then' of undefined
– Devchris
Nov 22 at 15:17




So I tried this but then it gives the error Cannot read property 'then' of undefined
– Devchris
Nov 22 at 15:17












2 Answers
2






active

oldest

votes


















0














You can use the Promise.all instead of using forEach



exports.deleteBooking = (req, res, next) => {
const promises = req.body.courts.map(element =>
Booking.deleteOne({$and: [
{ cid: element.cid },
{ year: element.day.year }
]})
);

Promise.all(promises).then((results) => {
// Handle the result response
})
.catch((error) => {
// Handle the error response
})
};





share|improve this answer





















  • Thanks a lot! This fixed the problem!
    – Devchris
    Nov 25 at 18:55



















1














res.status(201).json is within the forEach loop hence why you are getting the above error: you can only send data once.



To fix this, you basically need to send the deleteOne operations once and use bulkWrite() as it allows you to send multiple deleteOne operations to the MongoDB server in one command. It takes in input in form of an array of objects like the following



Booking.bulkWrite([
{ deleteOne: { filter: { cid: 1, year: 2007 } } },
{ deleteOne: { filter: { cid: 2, year: 2007 } } },
{ deleteOne: { filter: { cid: 3, year: 2007 } } },
{ deleteOne: { filter: { cid: 4, year: 2007 } } },
])


So in your case you can map req.body.courts array to the above deleteOne operations as



exports.deleteBooking = (req, res, next) => {
Booking.bulkWrite(
req.body.courts.map(({ cid, day }) => ({
deleteOne: { filter: { cid, year: day.year } }
}))
).then(message => {
res.status(201).json({ message })
}).catch(error => {
res.status(500).json({ error })
})
}





share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53433094%2ferror-handling-mongoose-with-foreach-loop%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    You can use the Promise.all instead of using forEach



    exports.deleteBooking = (req, res, next) => {
    const promises = req.body.courts.map(element =>
    Booking.deleteOne({$and: [
    { cid: element.cid },
    { year: element.day.year }
    ]})
    );

    Promise.all(promises).then((results) => {
    // Handle the result response
    })
    .catch((error) => {
    // Handle the error response
    })
    };





    share|improve this answer





















    • Thanks a lot! This fixed the problem!
      – Devchris
      Nov 25 at 18:55
















    0














    You can use the Promise.all instead of using forEach



    exports.deleteBooking = (req, res, next) => {
    const promises = req.body.courts.map(element =>
    Booking.deleteOne({$and: [
    { cid: element.cid },
    { year: element.day.year }
    ]})
    );

    Promise.all(promises).then((results) => {
    // Handle the result response
    })
    .catch((error) => {
    // Handle the error response
    })
    };





    share|improve this answer





















    • Thanks a lot! This fixed the problem!
      – Devchris
      Nov 25 at 18:55














    0












    0








    0






    You can use the Promise.all instead of using forEach



    exports.deleteBooking = (req, res, next) => {
    const promises = req.body.courts.map(element =>
    Booking.deleteOne({$and: [
    { cid: element.cid },
    { year: element.day.year }
    ]})
    );

    Promise.all(promises).then((results) => {
    // Handle the result response
    })
    .catch((error) => {
    // Handle the error response
    })
    };





    share|improve this answer












    You can use the Promise.all instead of using forEach



    exports.deleteBooking = (req, res, next) => {
    const promises = req.body.courts.map(element =>
    Booking.deleteOne({$and: [
    { cid: element.cid },
    { year: element.day.year }
    ]})
    );

    Promise.all(promises).then((results) => {
    // Handle the result response
    })
    .catch((error) => {
    // Handle the error response
    })
    };






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 22 at 15:19









    Med Lazhari

    26215




    26215












    • Thanks a lot! This fixed the problem!
      – Devchris
      Nov 25 at 18:55


















    • Thanks a lot! This fixed the problem!
      – Devchris
      Nov 25 at 18:55
















    Thanks a lot! This fixed the problem!
    – Devchris
    Nov 25 at 18:55




    Thanks a lot! This fixed the problem!
    – Devchris
    Nov 25 at 18:55













    1














    res.status(201).json is within the forEach loop hence why you are getting the above error: you can only send data once.



    To fix this, you basically need to send the deleteOne operations once and use bulkWrite() as it allows you to send multiple deleteOne operations to the MongoDB server in one command. It takes in input in form of an array of objects like the following



    Booking.bulkWrite([
    { deleteOne: { filter: { cid: 1, year: 2007 } } },
    { deleteOne: { filter: { cid: 2, year: 2007 } } },
    { deleteOne: { filter: { cid: 3, year: 2007 } } },
    { deleteOne: { filter: { cid: 4, year: 2007 } } },
    ])


    So in your case you can map req.body.courts array to the above deleteOne operations as



    exports.deleteBooking = (req, res, next) => {
    Booking.bulkWrite(
    req.body.courts.map(({ cid, day }) => ({
    deleteOne: { filter: { cid, year: day.year } }
    }))
    ).then(message => {
    res.status(201).json({ message })
    }).catch(error => {
    res.status(500).json({ error })
    })
    }





    share|improve this answer


























      1














      res.status(201).json is within the forEach loop hence why you are getting the above error: you can only send data once.



      To fix this, you basically need to send the deleteOne operations once and use bulkWrite() as it allows you to send multiple deleteOne operations to the MongoDB server in one command. It takes in input in form of an array of objects like the following



      Booking.bulkWrite([
      { deleteOne: { filter: { cid: 1, year: 2007 } } },
      { deleteOne: { filter: { cid: 2, year: 2007 } } },
      { deleteOne: { filter: { cid: 3, year: 2007 } } },
      { deleteOne: { filter: { cid: 4, year: 2007 } } },
      ])


      So in your case you can map req.body.courts array to the above deleteOne operations as



      exports.deleteBooking = (req, res, next) => {
      Booking.bulkWrite(
      req.body.courts.map(({ cid, day }) => ({
      deleteOne: { filter: { cid, year: day.year } }
      }))
      ).then(message => {
      res.status(201).json({ message })
      }).catch(error => {
      res.status(500).json({ error })
      })
      }





      share|improve this answer
























        1












        1








        1






        res.status(201).json is within the forEach loop hence why you are getting the above error: you can only send data once.



        To fix this, you basically need to send the deleteOne operations once and use bulkWrite() as it allows you to send multiple deleteOne operations to the MongoDB server in one command. It takes in input in form of an array of objects like the following



        Booking.bulkWrite([
        { deleteOne: { filter: { cid: 1, year: 2007 } } },
        { deleteOne: { filter: { cid: 2, year: 2007 } } },
        { deleteOne: { filter: { cid: 3, year: 2007 } } },
        { deleteOne: { filter: { cid: 4, year: 2007 } } },
        ])


        So in your case you can map req.body.courts array to the above deleteOne operations as



        exports.deleteBooking = (req, res, next) => {
        Booking.bulkWrite(
        req.body.courts.map(({ cid, day }) => ({
        deleteOne: { filter: { cid, year: day.year } }
        }))
        ).then(message => {
        res.status(201).json({ message })
        }).catch(error => {
        res.status(500).json({ error })
        })
        }





        share|improve this answer












        res.status(201).json is within the forEach loop hence why you are getting the above error: you can only send data once.



        To fix this, you basically need to send the deleteOne operations once and use bulkWrite() as it allows you to send multiple deleteOne operations to the MongoDB server in one command. It takes in input in form of an array of objects like the following



        Booking.bulkWrite([
        { deleteOne: { filter: { cid: 1, year: 2007 } } },
        { deleteOne: { filter: { cid: 2, year: 2007 } } },
        { deleteOne: { filter: { cid: 3, year: 2007 } } },
        { deleteOne: { filter: { cid: 4, year: 2007 } } },
        ])


        So in your case you can map req.body.courts array to the above deleteOne operations as



        exports.deleteBooking = (req, res, next) => {
        Booking.bulkWrite(
        req.body.courts.map(({ cid, day }) => ({
        deleteOne: { filter: { cid, year: day.year } }
        }))
        ).then(message => {
        res.status(201).json({ message })
        }).catch(error => {
        res.status(500).json({ error })
        })
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 at 15:33









        chridam

        65.9k12104137




        65.9k12104137






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53433094%2ferror-handling-mongoose-with-foreach-loop%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Berounka

            Sphinx de Gizeh

            Different font size/position of beamer's navigation symbols template's content depending on regular/plain...