Late last year i started training in Brazilian Jiu Jitsu. You can read about my journey from couch potato to BJJ student, over at my other blog, CouchJitsu. But as part of my journey, I went from just doing technique classes, to sparring and conditioning and even competing in a tournament. As I added more training, I got to be curious about what I was actually doing. So I started with a spreadsheet. As I added more complexity, I started realizing I should move it out of a spreadsheet and into an application. As I looked at writing this new application, I wanted to take the opportunity to learn something new.
Once I decided to make double use of my time by writing an application that will help me, and using it to teach me new things, I thought of a couple different options. Some of the products I considered using were:
- Ruby on Rails
I ruled out Ruby on Rails and Sinatra because I’d used them in my last little app. I ruled out WebAPI because I use it a lot at work, and it has some overlap with OpenRasta which I’ve had a lot of experience with. That left node.js, NancyFx and AngularJS as tools to play with. I didn’t give too much thought to node.js, and I don’t have a reason for that.
I did play around with NancyFx and thought I would have just a simple API that delivered JSON to the front end. But at the core, NancyFx was just going to be my delivery method. I started by TDDing some logic classes to handle my data.
What Does The App Do?
My core “business logic”, if we can use that word, is to track what classes I’ve been attending, and tell me how many of each class I went to each month and for the year. For example, I’d want to know that last month I did 10 conditioning classes and 12 technique classes. But I also was aware that people at my gym have different schedules than me. They might do BJJ, Muay Thai and/or Judo. In each of those there might be technique, conditioning and sparring. So I didn’t want to define the classes (or activities — since ‘class’ is a loaded word in programming.) I wanted to let each user tell the system what he/she did that day.
As a result, each user has a list of activities that they do on a regular basis. Each activity has a collection of records. Each record is nothing more than a date and an optional note. For example, here’s the part of my user record that contains my (one so far) tournament:
The application will pull all the activities for the user and given date. In addition to the date’s activities, it pulls two dashboards. One dashboard for the current month, and one for the current year. It will display the total number of records, as well as the top 4 activities and their count for the given time period. For example, listed below is my dashboard for the year as of April 1st:
How to Deliver It?
So once I nailed down what the application actually did, I went back to figure out how to deliver the content. I had tests in place that verified that my logic was correctly saving, fetching and summing the activities. So in that sense, my “application” was done. Everything that would be added from this point on would be polish and feel.
I initially chose NancyFx. I had found a NuGet package that would let me use Facebook, Twitter and/or Google to sign in. They even had one that was specific to NancyFx. So I set out to try and use that. I got a lot of the code up and running but I ran into a couple problems. One, I was completely unaware of how to do authentication in NancyFx. That’s not too surprising, considering I’d never used NancyFx before. But as I ran in to issues, i wasn’t sure if the problem was my lack of understanding of Nancy, a mis-configuration of my Facebook app, or with the World Domination package.
After spending, literally, a few hours on a Saturday night, I decided to abandon NancyFx and switch back to MVC. It wasn’t that NancyFx was the problem, I didn’t know what the problem was, but I’ve done plenty of authentication with MVC, so that was a known quantity. And based on the fact that my core application was in it’s own assembly, the only thing NancyFx was doing was proxying into my DLL, MVC could do that just as easily.
After I switched over to MVC I was still having a problem authenticating, but it was slightly different. I was having a problem getting the callback from Facebook. What this told me is that I probably had something screwed up in NancyFx. The problem with Facebook was that my redirect URL looked like this: http://localhost/mattime/ where MatTime was my application name. Facebook kept wanting to just redirect to localhost. To get around this, I created a subdomain and had Facebook redirect to http://mattime.localhost. With that change, all my authentication was done.
How Do I Display The Data?
Once I got the application running, and the MVC project delivering content, I needed to get it to actually look half-way decent. This is by far my weakest aspect in development. I had a rough idea of what I wanted it to look like. I was familiar with Bootstrap, and really enjoy what it does for me. I also had decided to use AngularJS as a client-side framework. After all, that was the only framework I was considering learning that I hadn’t eliminated. As I did some digging, I found out that AngularJS plays really nice with Bootstrap. Including several custom directives just for AngularJS.
But there was still a problem, how do I take the image from my mind, flesh it out, and have a consistent style? That’s when I looked up WrapBootstrap, which I’d heard about before. I browsed through the themes that were for sale, narrowed it down to a couple and finally decided on the one I’d use. What this really did for me was provide me with some styles that I could use throughout the site that would make it look consistent.
Once I got all of these parts working together, Mongo, C#, MVC, Bootstrap and a pseudo-custom template, all that I had left was to write the Angular. I was really pleased how easy it was to get up and running. It only took me a few minutes to get my main controller up and running, and then spitting out the tasks (using ng-repeat.) I then added two more controllers for the dashboard. This time, the two controllers took less than an hour.
In the end, I was pretty pleased with the version I initially released. I have some things I want to add to the site, but I also wanted to get it out there.
Lessons Learned And Remembered
- Don’t add unnecessary complexity. I started with a spreadsheet and used that until it became more complex to add functionality.
- Seize opportunities to learn new things. Nothing I did needed to be done in the way I did. Instead of Mongo, and AngularJS, I could have done with SQL and straight MVC Razor views, which were technologies I already knew pretty well.
- Focus first on the application. I worried about how I would deliver my data (MVC, Nancy, Angular etc) only after I had a working DLL with my business logic.
- Know your users. Most (if not all) of my users read my blog based on links from Facebook. So using that as the sole authentication provides own r would cover a very high percentage of my readers.
- Minimize the unknown. As I started struggling with the authentication I wasn’t sure if it was because of a mis-configuration of NancyFx, the NuGet package or Facebook. By switching back to MVC, I removed one unknown.
- Don’t be afraid to ship. There are still a couple bugs (mouse pointer in one area, and at least one friend’s phone doesn’t handle it well.) But it’s out there, if I waited for it to be perfect, I’d never deliver.
The GitHub repository has all the code (save Facebook API passwords etc.)