Writing a bill calendar with Node and Express
Everyone has their “go to” application when it comes to learning a new software stack. I believe every programmer out there has written the venerable “Hello World” application at least once in their lifetime. Todo apps were all the rage when Angular came on the scene. Some folks I know like writing blog applications. My app of choice is a bill calendar.
It may seem like a strange starting point when it comes to building a learning application, however date manipulation is one of those things that seems very simple on the surface but it is deceptive. You get that down and you can tackle almost anything.
The first time I wrote the bill calendar was with ColdFusion(Lucee) and ColdBox, but I thought it would be really cool to write a single page application using AngularJS. Alas, Angular is great on the client side but if you would like data to persist it requires a back end server. A bill calendar that requires you to enter everyone you pay every time the page is loaded would get monotonous quickly. I could easily write an API in ColdFusion to handle this, but it did give me an excuse to play around with NodeJS.
So here we are
The very first thing I did was to find a starting point. I could have very easily started with a bare-bones implementation of Express and built on top of that, but the NodeJS community is awesome so I did not have to reinvent the wheel. I found the hackathon-starter boiler plate app and was able to quickly get up and running. It almost feels like cheating since Express and much of the middleware has already been done for you, but at the same time it follows best practices and gives you user authentication with social sign-in from the gate. It is possible to jump right in and starting coding with some of the community driven boiler plate apps. If this one was not your cup of tea, simply pick another one!
Now that the foundation has been laid it is time to start to actually build something. The hackathon-starter app breaks the layout into several logical folders: config for your Passport configuration to handle user authentication, the controllers folder that hold the actual logic for your application routes, the models folder that contain the mongoose schema for items and finally a views folder that will hold our PugJS templates. App.js in the root of the folder structure that is the main file for the application and pulls everything together.
The next step is figuring out the structure of the data to retain. Since this is a bill calendar the name, a short description, due date, amount and the website URL would be fantastic to track . There are several other fields related to payees that are retained, but those are the important ones.
I also created a schema for payments so a payee can be marked as paid in the forecast view. If the payment amount changes each month we can also show the end user what the average payment amount is for that payee. That will require us to track the id of the payee, the id of the owner, the date the payment is due as well as the amount.
Once the data has been setup the real fun begins. The forecast is what really ties all these pieces together. Forecast.js in the controllers folder only has one route handler, the getIndex() function. This method will calculates the start date, gets a list of bills for the current week and will then proceed to the next three weeks.
Here is the overall flow of how the whole process works:
- Load the user’s current list of payees and build a schedule for the current month. Also get a sum of the total amount due each month.
- Load a user’s payments to see if it corresponds to a current bill and mark it paid
- Using MomentJS, determine the first day of the current week based on the user’s settings. By default the first day of the week is Sunday, but allow the user to define that value if they would prefer a different start day.
- Now it is just a matter of using MomentJS to determine if the due date falls in between the start date and end date. If so, add it to the weekly list and add the amount to the weekly total. Also look in the payment information to see if I can match a payment to the bill due date so it can be marked paid.
- This process continues for every week displayed on the forecast view.
Wrapping it all up
Overall my first real experience with Node/Express was very positive. The community around NodeJS in general is fantastic and if I hit a road block I could easily find an answer to my questions. I am looking forward to polishing up my bill calendar app, it has been a pleasure so far.
You can find all the source code for the application here as well as a link to the live site hosted with Now.