Using Moment.js to build a schedule component in React

I’ve been working on a project that included a weekly calendar showing reservations for a number of cabins on a family property. The calendar is a grid with 8 columns (Saturday through Saturday) and 7 rows representing the 7 cabins. The challenge is translating arrival/departure info saved as date objects in my Rails backend into a dynamic visual representation in React.

The native JS date object comes with some formatting methods, but doesn’t provide much easy support for manipulating dates (adding, subtracting, comparing). I thought of converting the dates to integers to do the necessary calculations , but crossing from one month to the next, with each month having a different number of days made this approach problematic.

Enter Moment.js (https://momentjs.com/).

Moment.js provides a wrapper for native java date objects that greatly expands the available methods including robust formatting, the ability to compare dates and easily add and subtract using a fairly obvious syntax.

Dates from the Rails api are returned as a string; ‘2020–05–30’. I first convert to js date appending ‘T00:00:00’ to give the date a sense of time zone, then I wrap the date as a Moment time object:

let arrival = new Date(`${res.arrival}T00:00:00`);
let arr = moment(arrival);

Once I have the weekly start date, arrival date and departure date as Moment objects I can make some calculations using native Moment methods:

numDays = (end, start) => {
return end.diff(start, ‘days’)
}

The code above calculates the difference between the end and start in days. Notice the syntax: ‘days’ for your result in days.

Using this function I create an array of the current reservations that includes each reservation as an array representing each day of that reservation. Each day is represented by an integer that is the difference between the current week’s start date and the reservation’s cur date.

allReservations = [res1, res2, res3] =>

res1 = [day1 (dif=2 (days after startOfCurWeek), day2 (dif=3 (days after startOfCurWeek), etc]

With the reservations parsed in this manner, I can locate all of the reservations that fall within a given week, and map the days to the appropriate div in my grid by rendering a Square component in the appropriate location.
If there is no reservation for that day and that cabin, the Square is left blank. I use the User info I’ve added to the reservation objects to add names to the individual Square components as well as a different color (drawn from a 6 color array that is assigned based on userId % 6 ).

Below is the result:

I waited to get a single week rendered before tackling the logic of displaying the previous or the next weeks, but adding or subtracting a week with Moment is as easy as:

moment(this.state.startDate).subtract(this.state.week, ‘week’).format()

I update my component’s state with the new startDate and voila, the new week is displayed along with it’s reservations.

Moment.js offers many more methods than I’ve used in my app, but the few that I did use helped simplify my work with dates immensely. I look forward to delving in deeper when I have a free moment.

Written by

After years of teaching music in Austin, Shanghai and Yangon, I’m making a career change to my other passion, software development.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store