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 '18 at 14:57











  • So I tried this but then it gives the error Cannot read property 'then' of undefined

    – Devchris
    Nov 22 '18 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 '18 at 14:57











  • So I tried this but then it gives the error Cannot read property 'then' of undefined

    – Devchris
    Nov 22 '18 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 '18 at 14:27









DevchrisDevchris

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 '18 at 14:57











  • So I tried this but then it gives the error Cannot read property 'then' of undefined

    – Devchris
    Nov 22 '18 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 '18 at 14:57











  • So I tried this but then it gives the error Cannot read property 'then' of undefined

    – Devchris
    Nov 22 '18 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 '18 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 '18 at 14:57













So I tried this but then it gives the error Cannot read property 'then' of undefined

– Devchris
Nov 22 '18 at 15:17





So I tried this but then it gives the error Cannot read property 'then' of undefined

– Devchris
Nov 22 '18 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 '18 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 '18 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 '18 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 '18 at 15:19









    Med LazhariMed Lazhari

    26215




    26215













    • Thanks a lot! This fixed the problem!

      – Devchris
      Nov 25 '18 at 18:55



















    • Thanks a lot! This fixed the problem!

      – Devchris
      Nov 25 '18 at 18:55

















    Thanks a lot! This fixed the problem!

    – Devchris
    Nov 25 '18 at 18:55





    Thanks a lot! This fixed the problem!

    – Devchris
    Nov 25 '18 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 '18 at 15:33









        chridamchridam

        67k15109140




        67k15109140






























            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.




            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

            Create new schema in PostgreSQL using DBeaver

            Deepest pit of an array with Javascript: test on Codility

            Costa Masnaga