1

I apologize for my poor way of explaining my issue. I am trying to update my schema's notes and assignmentHistory fields. I have no issues updating notes field but with the assignmentHistory field what I am trying to do is append values to the array only if the assingedTo value has changed from it's last value or is not empty only then $push to assignmentHistory array, otherwise don't add anything to assigmentHistory array. Basically, how do I prevent $push not add anything to the assignmentHistory array, not even empty object with _id field? Below is snippet of my code

const RequestSchema = new Schema(
  {
title: { type: String, required: true, max: 32, min: 6 },
priority: { type: String, emum: ["low", "medium", "high"] },
notes: [
      {
        commentNotes: {
          comment: { type: String, max: 200 },
          commentBy: { type: Schema.Types.ObjectId, ref: "User" },
          commentDate: { type: Date },
       }
]
assignedTo: { type: Schema.Types.ObjectId, ref: "User" },
assigmentHistory: [
      {
        techName: { type: Schema.Types.ObjectId, ref: "User" },
        assignedDate: { type: Date },
      }
    ]
}

let noteObj={};
let techobj={};

await RequestModel.findOneAndUpdate(
      { _id },

      {
        $push: {
          notes: [noteObj],
          assignmentHistory:[techobj]
        },
      },
      { new: true }
    );
funkybuddha
  • 53
  • 2
  • 9

2 Answers2

0

In order to only push an element in an array if the value is not present yet, you can use $addToSet. See this example on mongoplayground. Regarding handling the empty object - I'd just do it on the client side and dynamically build the query. So something like:

const addToSetObj = {};
if(!isEmpty(noteObj)) { // use one of the method for isEmpty described here https://stackoverflow.com/q/679915/3761628
  pushObj.notes = noteObj;
}
if(!isEmpty(techObj)) {
  pushObj.assignmentHistory = techObj;
}
await RequestModel.findOneAndUpdate(
      { _id },
      {
        $addToSet: addToSetObj
      },
      { new: true }
    );
eol
  • 23,236
  • 5
  • 46
  • 64
  • Thanks for your reply and introducing me to $addToSet . Is there a way to not even add an empty object in the assignmentHistory array field? Even if addToSetObj is empty it still add an empty object in the array ,$addToSet: addToSetObj. What I am trying to do is if addtoSetObj is empty then not even add {} to the array . T – funkybuddha Jan 30 '22 at 16:24
0

I do have a work around but would like a more professional way to avoid adding empty objects to the array field.

Basically, I only wanted to push an object to assigmentHistory array field of my schema if assignedTo variable was true. Good Programming doesn't recommend using same code twice, but in my case I have used the findoneAndUpdate query twice in the if and else condition. Please feel free to optimize it. All I want is when assignedTo variable is false , then $addToSet not add an empty object in the assignmentHistory array field.

if (
  assignedTo &&
  assignedTo.toString() !== oldRequest.assignedTo.toString()
) {
      await RequestModel.findOneAndUpdate(
        { _id },

        {
          $set: requestFields,
          $push: {
            notes: [noteObj],
          },
          $addToSet: { assigmentHistory: [newtech_info_object] },
        },
        { new: true }
      );
    } else {
      await RequestModel.findOneAndUpdate(
        { _id },

        {
          $set: requestFields,
          $push: {
            notes: [noteObj],
          },
        },
        { new: true }
      );
    }
funkybuddha
  • 53
  • 2
  • 9
  • Your answer could be improved by adding more information on what the code does and how it helped you. – Tyler2P Jan 30 '22 at 20:30
  • As I have mentioned in my edited answer , all I was trying to achieve is not add an empty object to an array field of the schema. Hope I have made it clearer now. – funkybuddha Feb 01 '22 at 14:49