I have a business hours object in a mongoose schema that represent a date. I'm passing a json object and retrieving the to parse to Date as string. I wonder if you can or if it will be better to represent it as another type of object. Error I get when passing like this is: validation failed: business.businessHours.monday.startTime: Cast to date failed for value "08:00" (type string)
A work around would be setters which will add current date with hours and minutes:
date.setHours(08);
date.setMinutes(30);
I feel like there is a better way to this. Is there a way to pass a date object in json?
my json is:
{
...,
"businessHours":{
"monday": {
"startTime": "08:00",
"endTime": "18:30"
},
"tuesday": {
"startTime": "08:00",
"endTime": "18:30"
},
"wednesday": {
"startTime": "08:00",
"endTime": "18:30"
},
"thursday": {
"startTime": "08:00",
"endTime": "18:30"
},
"friday": {
"startTime": "08:00",
"endTime": "18:30"
},
"saturday": {
"startTime": null,
"endTime": null
},
"sunday": {
"startTime": null,
"endTime": null
}
}
}
The schema looks like this:
const sellerSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
unique: true,
},
...,
business: {
businessHours: {
monday: {
startTime: {
type: Date,
},
endTime: {
type: Date,
},
},
tuesday: {
startTime: {
type: Date,
},
endTime: {
type: Date,
},
},
wednesday: {
startTime: {
type: Date,
},
endTime: {
type: Date,
},
},
thursday: {
startTime: {
type: Date,
},
endTime: {
type: Date,
},
},
friday: {
startTime: {
type: Date,
},
endTime: {
type: Date,
},
},
saturday: {
startTime: {
type: Date,
},
endTime: {
type: Date,
},
},
sunday: {
startTime: {
type: Date,
},
endTime: {
type: Date,
},
},
},
}
I know I can convert it before I save it, but is there a way to parse a string with only hh:mm to date? I can't seem to find a way, or would it be better to just represent it as a different object and what object would be the ideal for this occasion.
or should I have a schema like:
I need the hour and minutes for future logic.
const sellerSchema = new mongoose.Schema({
...,
business: {
businessHours: {
monday: {
startTime: Number, //which will be represented as HHMM
endTime: Number, //which will be represented as HHMM
},
},
},
});
Thank you
CodePudding user response:
It does not make a big difference whether you use values like "18:30"
or 1830
. One is a bad as the other one.
Values like "18:30"
are strings, you cannot cast them into a Date
. If you like to do this, then you must have a full date/time string, e.g. "2022-05-06T18:30:00". However, you should never store date values as string, it's a design flaw. Store always proper Date
objects!
Using weekday names is also a bad idea, MongoDB does not support (localized) weekday names natively. It's also a poor design to have dynamic field names.
I would suggest this one:
{
businessHours: [
{ dayOfWeek: 1, startHour: 8, startMinute: 0, endHour: 18, endMinute: 30 },
{ dayOfWeek: 2, startHour: 8, startMinute: 0, endHour: 18, endMinute: 30 },
...
{ dayOfWeek: 5, startHour: 8, startMinute: 0, endHour: 18, endMinute: 30 }
]
}
According to ISO-8601 weeks start on Monday, thus dayOfWeek: 1
means Monday.
Then you can create easily Date
values from it, for example like this:
{
$dateFromParts : {
'isoWeekYear': {$isoWeekYear: "$$NOW"},
'isoWeek': {$isoWeek: "$$NOW"},
'isoDayOfWeek': "$dayOfWeek",
'hour': "$startHour",
'minute': "$startMinute"
}
}
If you use weekday names, then you would have to deal with $switch or you need a 3rd party library like moment.js, luxon or Day.js.