0

Hello I am looking to implement a way to dynamically insert new fields to an existing mongoDB document from the server side with node.js and express.

For example in the local mongoDB the document looks like this.

 {
 value: 'Google',
  url: 'https://google.com',
  env: 'Test'
 }

I have a route that will already update the current document fields from a form on the UI. However I want to combine that logic with the ability to insert new fields upon updating.

The route below handles updating the document with the existing fields.

router.put("/:id", (req, res) => {
  let value = req.body.value;
    Application.findByIdAndUpdate(req.params.id, req.body.application, (err, 
       updatedApp) => {
      if(err){
        console.log(err);
      } else {
        console.log(updatedApp)
        req.flash("info", updatedApp.value  + " " + "successfully edited!");
        res.redirect("/qa-hub/applicationmanager");
      }
    });
});

On the front end I use EJS with a form to update the document. Example below:

<div class="row">
      <div class="col-md-6">
        <div class="form-group">
          <input class="form-control" type="url" name="application[url]" value="<%= application.url %>" required>
        </div>
      </div>
    </div>

    <div class="row">
      <div class="col-md-6">
        <div class="form-group">
          <select class="form-control" name="application[env]" required="true">
            <option class="text-center" value='<%= application.env %>'><%= application.env %></option>
            <option value='Beta'>Beta</option>
            <option value='Dev'>Dev</option>
            <option value='Does Not Apply'>Does Not Apply</option>
            <option value='Prod'>Prod</option>
            <option value='QA'>QA</option>
            <option value="Test">Test</option>
          </select>
        </div>
      </div>
    </div>
    <div class="row">
      <div class="col-md-4">
        <div class="form-group">
          <a class="btn btn-outline-warning" href="/qa-hub/applicationmanager">Cancel</a>
        </div>
        <div class="form-group">
          <button class="btn btn-outline-primary" id="btn" >Update</button>

However i'd like to add three additional fields upon submitting the form. I want to capture the currently logged in user that performed the edit and the date and time. I already have that worked out but how could I implement inserting new data to the existing document from the route.put while also keeping the logic to update the current fields if any changes are made.

So after the user makes some changes and updates the three fields the document would look something like below, except id handle the logic to get the currently logged in user at that time and the date/time and pass it in but for the example below I will hardcode it.:

{
 value: 'Google',
  url: 'https://google.com',
  env: 'Test',
  updatedBy: "Test User"
  timeUpdated: "12:54",
  dateUpdated: "7/25/2018"
 }

So ultimately I want to keep a log of the changes and than be able to add it to the UI.

1 Answer 1

0

So with a little help from this post TypeError: callback.apply is not a function (Node.js & Mongodb) I was able to append new fields to the existing document using $set. However when trying to perform the req.body.application before $set it would throw an error stating that callback.apply is not a function. So I just created a callback if you will to update the document after setting the new fields. I know its messy but just wanted to get it working feel free to use and clean up the code for your self.

    router.put("/:id", (req, res) => {
      let value = req.body.value;
  let value = req.body.value;
  let date = new Date();
  let hour = date.getHours();
  hour = (hour < 10 ? "0" : "") + hour;
  let min = date.getMinutes();
  min = (min < 10 ? "0" : "") + min;
  let time = hour+":"+min;
  let year = date.getFullYear();
  let month = date.getMonth() + 1;
  month = (month < 10 ? "0" : "") + month;
  let day  = date.getDate();
  day = (day < 10 ? "0" : "") + day;
  today = month+"/"+day+"/"+year;
  let updatedTo = month+"/"+day+"/"+year;
  let updatedT = hour+":"+min;
  let updatedBy = req.user.username;
    //Find the document based on it's ID and than append these three new fields
        Application.findByIdAndUpdate(req.params.id,
        { $set: { 
               updatedTime: `${updatedT}`,
               updatedToday: `${updatedTo}`,
               updatedBy: `${updatedBy}`
        }}, { upsert: true },
          (err,updatedApp) => {
          if(err){
            return handleError(err);
          } else {
         // Than if any changes were made from the UI we apply those updates taken 
         // from the form with req.body.application
          Application.findByIdAndUpdate(req.params.id, req.body.application,
          (err, updatedApp) => {
          if(err){
           return handleError(err);
          } else {
            console.log(updatedApp)
            req.flash("info", updatedApp.value  + " " + "successfully edited!");
            res.redirect("/qa-hub/applicationmanager");
           }
        }
      });
   });
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.