Innovate / Nutrition Manager
Nutrition Manager
A reflection on an old nutrition project
As an activity to better comprehend the software development MVC (Model View Controller) framework in 2018, I decided to throw together a web application to help me meet my daily fundamental nutritional needs with some help from Scott Herman.
So I kicked things off with plans for simply a profile page and main management page which would satisfy all the use cases. I started by marking up the HTML (This being the View portion of MVC) with coloured boxes to match my sketched design and gradually started to implement standard HTML tags to bring the template more obvious utility. As time went on and business logic became refined, I started to leverage the ASP.NET Core Razor syntax, which just allowed me to programatically inject data into the DOM (Document Object Model) (The HTML essentially), but more on that later.

I definitely started to develop learnings at this time around how dumb it is to write business logic on the front end and different HTML coding standards (dumb because we don't want duplicate reasoning across a platform. It's very unfriendly for scalability).
Anyway dope, we have a template for both of our pages, I then wanted to add some network routing between the two and some routing for our front end to talk to our backend. This can generally be achieved with a combination of AJAX (Asynchronous Javascript And XML) and the MVC Controller in the back end. AJAX calls work by sending a request out to the web server and interpreting a response. One of the biggest challenges I faced with AJAX was how, for modals, the request would trigger a page reload before the request could catch a response while the modal closed. This meant that the page would refresh and the server response wouldn't know which AJAX instance made the request, which then meant that we couldn't trigger any functionality based on of success or failure. After consulting my friends, the solution we came up with was adding a promise to the AJAX request which ensures synchronicity for asynchronous functions so that we could interpret the response and finally force the DOM to re-render at the end.

From here we started to implement some basic business logic; in fact, for this project all of the business logic was very straight forward and used simple maths.

I then continued to move to data storage. Since this project was low-key, I couldn't be bothered spinning up and hosting a SQL Server and using Dapper or anything to overcomplicate it. So I settled on a basic JSON (Javascript object notation) structure. With .NET's JSON libraries, this is extremely easy to implement. Both implementation and file structure are as below. I constructed the APIs (Application Programming Interface) such that if you provided the carbs, proteins, and fats, it would calculate the calories. If you didn't know any of that information but for some reason had the calories, it would try to approximate the other values.


Okay swell, all the groovy backend sorted. We have functional APIs and a method of storing data, it's time to get to that juicy front end. It took a bunch of iterations but I finally settled on a front end styling that I liked and persisted it across all my future front end work - leveraging the shit out of Flex. I decided to structure the naming of my CSS (Cascading style sheet - what makes web pages pretty) using a BEM (shown below) naming philosophy; because hot-damn, did I write a lot of styling by hand without importing anything existing like Bootstrap - so we need some structure to the madness.


I started with the profile page. We had our navigational button at the top and key fields. I decided to set mutable fields on the left of the page and immutable fields on the right. For a better user experience, whatever you change on the page would automatically update the immutable fields - which is probably why I was a goober and put business logic on the front end. I designed this page for me to architect my fats and protein needs because I wasn't focusing on the benefits of carbs.

For a better user experience I formulated a nice little edit screen for each field that wouldn't allow submits until data had changed and would validate if you were inputting incorrect data.

On to the home page!

Okay, let's break it down. I started with a food database. This kept track of everything we've stored and provides us a scrollable list of those foods and how many calories they are - all neatly kept in a bezelled box of a fixed size. As I mentioned earlier, we were able to inject this onto the page with Razor's syntax. For readability, each element automatically colours the background in alternating white and grey and has a distinct blue hover effect (seen above) to identify what you're considering selecting; and of course, a unique green selection colour. On the left, we notice some functional buttons with some greyed out to help users understand what they can and can't do without the need for instructions. Selecting a food enables these other options, as well as the ability to add it to the consumed list which we will get to soon.



Each of these options opens up a modal. Immediately, we can see how it blurs the background to help us focus on what we're trying to do, and will not allow us to complete the function until all the fields contain appropriate data (or in the case of editing, has changed at all). Below is a good example of input validation which I've placed across all text fields and leverages REGEX (Regular Expressions) to identify invalid input. Retrospectively, this was a bit overkill but I was having fun. All I should have done was set the HTML input to only accept numbers and nothing more was necessary since the numbers didn't need any complex input.


I moved on to implementing the consumed list. This kept track of all the foods we had eaten and saved it to our "database" so we could resume our "session" if we ever closed the window. I wanted to give a really organic feel to moving items, so the arrows on the left of the below screenshot were used to give the feel of moving an item to the consumed list or throwing it back. Each button had a hover effect and an enabled/disabled effect. There was a bit of fun with the javascript side of this to ensure that selecting multiple items in either list didn't cause anything that would damage the user experience. I monkey tested the hell out of this. There is a lot more happening here but we will discuss that in the next section.

The final component to the home page was a metrics screen. This one helped us see our progress of all the foods shooting around. The statistics field told us how many fats, carbs, protein, and calories we would have allocated for a day and how much we had consumed as well as a total kg metric at the bottom that gave us an estimated amount of how much we had gained or lost. Although this is useful, I felt I needed to concentrate too much to get an idea of where I was at, so I decided to add a coloured bar below each metric which would span the length of the box to give me a much better feel for how I was doing. Additionally, I colour coded the fields with green and red simply meaning good and bad.

If we had exceeded one of our goals, it would colour the bar red and cap its limit to the 100% of its full width. Another fun little function I put into the page to give the utility more of a techy feel that we can't see in the screenshots, was to have the bars animate on page load - they would grow from left to right to give us a feeling of accumulation. Also notice the colour of the text in our food database in the below screenshot (and the first homepage screenshot above). Whenever we add a food, my software figures out which of the items in our database would exceed any of our goals if we were to consume them next and grey them out as to not recommend them, although they can be moved across still. And finally, there is a reset button to start out day again :)

I started this project to get a better understanding for the software I was working on for the company I was at, at the time. It taught me a lot and I have since learned so much more. I would encourage everyone wanting to learn something to just deep dive into it and start making something out of what you know! Thanks for sharing my trip down memory lane!