Introducing expiRATION: An Exercise in Situational Innovation

Kyle Cole
6 min readMar 29, 2020

It’s March 2020. The entire world is under shelter-in-place orders due to the COVID-19 Pandemic. Society is self-quarantining to prevent further spread of this virus. Bars and Restaurants are closed. Companies big and small have shifted to 100% remote workplaces. Large gatherings—Concerts, Music festivals, and weddings—are all cancelled for the upcoming summer months. Entire sports seasons have been put on hold or cancelled. The 2020 Summer Olympics, postponed to 2021. Stuck at home for the foreseeable future, people have flocked to grocery stores and bought up all the chicken, frozen vegetables, and toilet paper (if they’re lucky enough to find any).

We’re facing widespread shortages on both consumer products and medical equipment. Businesses are getting creative—distilleries across America have retrofitted their equipment and have begun to manufacture hand sanitizer. GM will soon halt automobile production at one facility to start manufacturing ventilators instead. Anheuser-Busch has donated a sizable portion of their sports budget for the year to the Red Cross (approx. $5 million, minus what they’ve spent on all the ads telling consumers this, of course).

It’s an interesting time we’ve found ourselves in; this something that most of us have never experienced before. Those who were alive during the 1952 Polio epidemic are now the most at risk for COVID-19; and many of them were so young at the time that they likely don’t even remember the Polio outbreak.

Hard times have always sparked innovation. During the depression out of work Americans were looking for a way to pass the time that didn’t cost money. Board games with the goals of buying and selling property and creating words from tiles became a family favorites. Today, we know this games as Monopoly and Scrabble. The electric razor was invented when some guy in Alaska grew tired of shaving with cold water. Radar was created during WWII as a way to help pilots avoid thunderstorms.

As my wife and I started preparing for our inevitable staycation, we too found ourselves in ransacked grocery stores. We had a list but couldn’t stick to it, everything was sold out. Instead of chicken breast, we found ground Lamb. Instead of steaks we went home with chunk stew meat. We’re not trying to hoard supplies, but we also don’t want to go back to the store and risk exposure for a while. We grabbed what we could find for canned goods, the last can of black beans in the aisle, and headed home.

As we were unpacking the groceries into the already very full freezer my wife looked at me and said “Can you make me an app that will tell me what’s going to expire in here first? I want to make sure that we’re not wasting any food for the next few months.” I stopped what I was doing and thought about about it for a minute. This is it. This is the app we need right now. We didn’t need it a month ago, but today we need to ration our food. This was Situational Innovation.

I said to her confidently “Of course I can make that.”

I started sketching out some ideas and showed her some wireframes. She immediately provided feedback — “How do I know how much of something I have?” “Can I specify a category? What If I want to search all vegetables?” “I want a button to advance the expiration date by one day.” “Could my coworker use this too?” — I now had user stories and was ready to build.

All things considered, the app had relatively simple core functions:

  1. As a user, I want to add an item to my inventory
  2. As a user, I want to record an expiration date, category, and location for each item
  3. As a user, I want a list of all my items sorted by expiration date
  4. As a user, I want to filter the items by location and category
  5. As a user, I want to be able to modify the expiration date of an item

I chose to use Rails/React for this project because I knew that I could get something built fairly quickly. If I had chosen to work with a new framework it would only delay the project which the client (my wife) was already antsy for.

I sat down and started hacking away. My client wanted a skateboard by the end of the weekend. After setting up my rails associations I quickly had an API up and running with some seed data. The first task was to display the items. I fetched the data from my backend and mapped it to an unordered list; with each list item being a list of it’s own properties—name, category, location, expiration_date—it wasn’t pretty but it was the data I was looking for.

I decided my next step was to display the items sorted by expiration date rather than ID; that is the whole purpose after all. I proceeded to apply a .sort() to the data but pretty quickly determined that Fri, 27 Mar 2020 12:00:00 UTC +00:00 was not a format that was going to work for this app. I had a flashback to my last experience with date-times — I really wanted the app to say “Expiring Tomorrow” but didn’t really want to calculate how many days in the future an event was; that was a can of worms I wasn’t ready to open.

Thats when I remembered about Moment.js, a javascript package that was recommended to me after building my travel app and struggling with the conversion of all date-times to milliseconds to pass them between Ruby and Javascript. I had looked at the package documentation briefly, but had never actually implemented it.

Moment.js works very much like the default Date object in Javascript, you instantiate a new Moment with an optional argument of a date-time value. If no value is provided, a date-time object representing the current date-time will be created. Moment objects have various methods that can be called on them that affect the returned value:

Format Dates
moment().format(‘MMMM Do YYYY, h:mm:ss a’);
// March 29th 2020, 7:25:52 pm
moment().format(‘dddd’);
// Sunday
moment().format(“MMM Do YY”);
// Mar 29th 20
moment().format();
// 2020–03–29T19:25:52–04:00
Relative Time
moment(“20111031”, “YYYYMMDD”).fromNow();
// 8 years ago
moment().startOf(‘day’).fromNow();
// 19 hours ago
moment().endOf(‘day’).fromNow();
// in 5 hours
moment().startOf(‘hour’).fromNow();
// 26 minutes ago
Calendar/Time Math
moment().subtract(10, ‘days’);
// 03/19/2020
moment().subtract(6, ‘days’).calendar();
// Last Monday at 7:25 PM
moment().subtract(3, ‘days’).calendar();
// Last Thursday at 7:25 PM
moment().subtract(1, ‘days’).calendar();
// Yesterday at 7:25 PM
moment().calendar();
// Today at 7:25 PM
moment().add(1, ‘days’).calendar();
// Tomorrow at 7:25 PM
moment().add(3, ‘days’).calendar();
// Wednesday at 7:25 PM
moment().add(10, ‘days’).calendar();
Comparisons
moment('2020-03-29').isSame('2020-03-29');
//true
moment('2010-10-20').isBefore('2010-10-21');
// true
moment('2010-10-20').isAfter('2010-10-19');
// true

These formatting methods changed the game when creating this app! Using Moment.js allowed me to very easily display the number of days until something expired without having to get into complex date-time math. It even allowed me to do some conditional styling on my components! As the expiration date gets closer, the color changes. The experience was way easier than my previous attempts to compare date-times and calculate hours on my own. A wise man once said not to re-invent the wheel; I definitely agree.

As for the app, it’s called expiRATION— a combination of Expiration and Ration. I’ll follow up with a link once it’s live but for now you can checkout the codebase on github. It’s not really styled yet and I’m still ironing out some bugs, but my wife has started to use it to track our rations! As the inspiration behind this all, she has been a great beta tester! She even showed a few colleagues on a Zoom chat the other day; they all want to use it too! In the meantime, I’ll be making the most of my quarantine by putting the finishing touches on an idea that resulted from a tough situation.

cakehole out.

--

--

Kyle Cole

kcole => cakehole; Coder | Designer | Abstract Thinker | Co-resident of Planet Earth | Music Enthusiast