Search code examples
javascriptnode.jsmongodbmongooseejs

Updating MongoDB Database From Client Side


I'm making something of a quiz app, and I'm creating an edit page for each quiz ID to edit the specific question/answer.
However, the QuizID always returns as undefined at the end of an edit.

I've tried switching between"id" and "_id". I'm using the findByIDAndUpdate method

This is the part of the app.js

app.get('/edit/:id', async (req, res) => {
    try {
        const quizId = req.params.id; // Assuming the ID is passed as a route parameter
        const quiz = await Quiz.findById(quizId); // Fetch the quiz item from MongoDB
        res.render('editQuizID', { quiz }); // Render the edit form with the quiz details
    } catch (error) {
        console.log(error);
        res.redirect('/'); // Redirect  to handle errors
    }
});

app.post("/completeEdit", function (req, res) {
    const quizId = req.params.id; // Access the ID from the form submission
    const editedQuestion = req.body.editQuestion;
    const editedAnswer = req.body.editAnswer;

    console.log(editedQuestion, editedAnswer)

    const updateDocument = async (quizId) => {
        try {
            const updatedResult = await Quiz.findByIdAndUpdate(
                quizId,
                {
                    question: editedQuestion,
                    answer: editedAnswer
                },
                { new: true }
            );
            if (updatedResult) {
                console.log("Quiz updated:", updatedResult);
                res.redirect('/');
            } else {
                console.log("Quiz not found.", quizId);
                res.redirect('/');
            }
        } catch (error) {
            console.log(error);
            res.redirect('/');
        }
    };

    updateDocument(quizId)

});

app.listen(4000, function () {
    console.log("Server running on port 4000");
});

This is the ejs file for the edit page


<h1>Make An Edit</h1>
<form action="/completeEdit" method="post">
    <div class="edit-window-content">
      <label>Question</label>
      <input class="question-edit-box" type="text" name="editQuestion" placeholder="Edit question" value="<%= quiz.question %>">

      <label>Answer</label>
      <textarea class="answer-edit-box" type="text" name="editAnswer" rows="4" cols="30" placeholder="Edit answer"><%= quiz.answer %></textarea>
      
      <input type="hidden" name="id" value="<%= quiz.id %>">
      <button class="overlay-close" type="submit" name="button">Done</button>
    </div>
  </form

Solution

  • Firstly, you can't access a parameter from req.params if it is not included in the route handler definition. I can see you are sending the id in your form submission here:

    <input type="hidden" name="id" value="<%= quiz.id %>">
    

    So inside of your route handler just extract it from req.body instead.

    Secondly you don't need to define an updateDocument function just to call it on the next line, just make your route handler callback function async. A finished route handler with these changes might look like:

    app.post("/completeEdit", async function (req, res) { //< Mark as async
       const quizId = req.body.id; //< change to this
       const editedQuestion = req.body.editQuestion;
       const editedAnswer = req.body.editAnswer;
    
       console.log(editedQuestion, editedAnswer)
       try {
          const updatedResult = await Quiz.findByIdAndUpdate(
             quizId,
             {
                question: editedQuestion,
                answer: editedAnswer
             },
             { new: true }
          );
          if (updatedResult) {
             console.log("Quiz updated:", updatedResult);
             res.redirect('/');
          } else {
             console.log("Quiz not found.", quizId);
             res.redirect('/');
          }
       } catch (error) {
          console.log(error);
          res.redirect('/');
       }
    });