4
\$\begingroup\$

I have a series of Events (roughly 10-20 events that will be dynamically created per month):

Event Model:

import { Schema, model } from "mongoose";
const eventSchema = new Schema({
 callTimes: { type: Array, of: Date, required: true },
 eventDate: { type: Date, required: true },
 employeeResponses: [
 {
 _id: {
 type: Schema.Types.ObjectId,
 ref: "User",
 required: true,
 },
 response: { type: String, required: true },
 notes: String,
 },
 ],
 scheduledEmployees: [
 {
 _id: { 
 type: Schema.Types.ObjectId, 
 ref: "User", 
 required: true 
 },
 callTime: { type: Date, required: true },
 },
 ],
});
export default model("Event", eventSchema);

Some sample data:

[
 {
 "_id": "5d5daaafcf11d95c0a75a023",
 "callTimes": [
 "2019-08-21T10:30:41-07:00",
 "2019-08-21T11:00:41-07:00",
 "2019-08-21T11:30:41-07:00"
 ],
 "eventDate": "2019-08-20T02:30:36.000Z",
 "employeeResponses": [],
 "scheduledEmployees": []
 },
 {
 "_id": "5d5b5ee857a6d20abf49db19",
 "callTimes": [
 "2019-08-19T17:15:43-07:00",
 "2019-08-19T17:45:43-07:00",
 "2019-08-19T18:15:43-07:00",
 "2019-08-19T19:00:43-07:00"
 ],
 "eventDate": "2019-08-21T02:30:36.000Z",
 "employeeResponses": [
 {
 "_id": "5d5b5e952871780ef474807b",
 "response": "Available to work.",
 "notes": "I can work all day."
 },
 {
 "_id": "5d5b5e952871780ef474807c",
 "response": "Not available to work.",
 "notes": "I have school during that time."
 }
 ],
 "scheduledEmployees": []
 }
 ...etc
]

Employees can view a form that includes the current month's events and add their responses. However, I'm running into a predicament with creating/updating sub documents dynamically. I'm trying to create a bulkWrite function that will either create an employeeResponse sub document if none exists or update the sub document if it's already been created.

I came up with this function, where:

  • _id contains the form id
  • response is an object that contains the event's ObjectId, the employee event response (value), and an updateEvent boolean flag
  • notes are employee event notes
  • userId (req.session.user.id) is the current logged in employee stored in an express-session

Update Event function:

const updateFormAp = async (req, res) => {
 try {
 const { _id, responses, notes } = req.body;
 if (!_id || !responses) throw "Missing required update event parameters. You must include an event id and response.";
 const formExists = await Form.findOne({ _id });
 if (!formExists) throw "Unable to locate that event form.";
 // iterate over responses and update the Events accordingly...
 await Event.bulkWrite(
 responses.map(response => {
 try {
 const { id: eventId, value, updateEvent } = response;
 const { id: userId } = req.session.user;
 // if the employee response exists...
 const filter = updateEvent
 ? {
 // set the filter to event id + employee id
 _id: eventId,
 "employeeResponses._id": userId,
 }
 : {
 // else set the filter to event id only
 _id: eventId,
 };
 // if the employee response exists...
 const update = updateEvent
 ? {
 // update the sub document in place
 $set: {
 "employeeResponses.$.response": value,
 "employeeResponses.$.notes": notes,
 },
 }
 : {
 // else add a new sub document
 $push: {
 employeeResponses: {
 _id: userId,
 response: value,
 notes,
 },
 },
 };
 return {
 updateOne: {
 filter,
 update,
 },
 };
 } catch (error) {
 throw error;
 }
 }),
 );
 res
 .status(201)
 .json({ message: "Successfully added your responses to the A/P form!" });
 } catch (err) {
 res
 .status(400)
 .json({ error: err.toString() });
 }
};

So, if an event was added after some responses were recorded, the employee can go back and add their response to this newly created event while optionally updating their other responses as well.

Is there another or better approach to handling all 3 cases?

  1. No Event employeeResponses sub documents exists for the logged in employee, create them
  2. One or many Events don't contain employeeResponses sub documents for the logged in employee, create them
  3. One or many Events already contain employeeResponses sub documents for the logged in employee, update them.
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Aug 21, 2019 at 23:41
\$\endgroup\$

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.