1

I have a MongoDB collection (SlopeDay) that has dates stored.

enter image description here

In my express routing, I'm looking to format the date to MM-DD-YYYY so that I can use that for the URL. That URL will find all documents with matching dates AND matching resortNames.

dateRouter.get("/:formattedDate", (req, res) => {
  const formattedDate = req.params.formattedDate;

  SlopeDay.find({}) // isolate dates
    .then((dateObj) => {
      dateObj.forEach((date, i) => {
        let dateStr =
          // MM-DD-YYYY reformatting to string
          ("0" + (date.date.getMonth() + 1)).slice(-2) +
          "-" +
          ("0" + date.date.getDate()).slice(-2) +
          "-" +
          date.date.getFullYear();
         // map below doesn't seem to be doing much
        const objWithFormattedDate = dateObj.map((obj) => {
          return { ...obj, formattedDate: dateStr, isNew: true };
        });
        // console.log(objWithFormattedDate);
      });
    });
});

I'm at a loss for how to do this properly. I need the get route to access all SlopeDay documents matching dates to the MM-DD-YYYY parameter URL.

Viet Nguyen
  • 2,285
  • 2
  • 26
  • 43
jacver
  • 63
  • 6
  • Are the dates in all of your objects stored with no time data? If so, with a little bit of date reformatting, you can pass the param into the `.find()` query without having to do the forEach/map stuff. – MForMarlon Apr 22 '22 at 00:27
  • 1
    Eventually I'd like them to have no time data. There's no reason to include time in the app. I've made some progress so far with SlopeDay.find({ date: { $gte: new Date("04-13-2022"), $lt: new Date("04-15-2022"), }, – jacver Apr 22 '22 at 00:52

2 Answers2

1

I'm able to get it working by breaking the strings up and querying that way:

dateRouter.get("/:formattedDate", (req, res) => {
  const formattedDate = req.params.formattedDate;

  // break up the date
  const targetChars = formattedDate.substring(3, 5);
  const beforeTargetChar = formattedDate.substring(0, 3);
  const afterTargetChar = formattedDate.substring(5);

  // create lower and upper boundaries that straddle the formatted date
  const lowerbound = beforeTargetChar + (targetChars - 1) + afterTargetChar;
  const upperbound =
    beforeTargetChar + (Number(targetChars) + 1) + afterTargetChar;

  SlopeDay.find({
    date: {
      // find docs with dates between the boundaries (THIS SHOULD EQUAL req.params.formattedDate)
      $gte: new Date(lowerbound),
      $lt: new Date(upperbound),
    }, // add 2nd query here
  }).then((dateData) => res.send(dateData));
});

jacver
  • 63
  • 6
  • 1
    Glad you found a solution :) What you did is fine, but you can make things easier for yourself by splitting the formattedDate by the hyphen so you don't have to do the substring stuff. `const dateParts = formattedDate.split('-')`, then you have the month in dateParts[0], day in dateParts[1], and year in dateParts[2]. – MForMarlon Apr 22 '22 at 21:56
  • 1
    ha! Brilliant. So obvious too. Sometimes I get so laser focused on forcing something to work I miss the easiest way to do it. Thanks for the help! – jacver Apr 22 '22 at 22:24
0

Just using Javascript I can recommend this post that might help

Otherwise, there are many libraries you could use to do this as well. Personally I like using Day.JS. Their format function it would look something like this and should fit your needs and more if you wanted to take that route.

dayjs(yourDateHere).format('MM-DD-YYYY')

cheers!

jshehane
  • 66
  • 5
  • Interesting - I'm relatively new and had no idea about this. I'll check the library out - thanks! – jacver Apr 22 '22 at 00:55