Some Reflections on Coding MEAN

I've got strength-tracker basically functional, using the MEAN Stack (Mongo, Express, Angular, Node).  Still some stuff I want to do with it, but I figured I'd pause for some reflection on the technology and effort so far.
StrengthTrackerScreenshot

Directives are Widely Available

I came in thinking I would need to write directives for things like charting and modals, but I found that what I needed and more were available and free, and I could easily install them via bower.  I had seen a conference talk on Chartist and figured I'd try it out, and immediately found an angular project on github for it, which essentially required me to just create a json object for chart details and save it to scope.   Same thing when I needed a bootstrap modal.  I immediately found that there was a Bootstrap directive integration.  Angular has an active and thriving open source community around it.  If someone needs a directive that's not around, it looks like they just create it and throw it on github.

Jasmine Rocks

I enjoy readable Unit tests, so Jasmine was right up my alley.  I used it along with Karma for unit testing.  Karma allowed for continuous running of my tests while I was developing, which was awesome.  The quirk about Karma was it didn't give me an out of the box way to show the human readability of Jasmine, the thing that Jasmine excels at.  Never fear though, a quick google search brought me to karma-html-reporter, which gave me exactly what I needed (see below).   It describes the system behavior, which is not bad for unit tests:-)  Jasmine and angular have some mocking technology built in, and I did use it's "spy" capability for a couple of assertions around calls being made, but I found that with javascript its really easy to create stub objects.  Also, I liked Angular's pattern of dependency injection because it made for easy stubbing of services when testing controllers.
StrengthTrackerJasmineReport

JavaScript on Client, Server, and Database meant no Data Transformations

Yeah that's right.  The same json I kept in the UI as model is exactly what I was storing in the database.  I'm not used to this with as much with my years using java and sql on the server side, and it was pretty refreshing.  Traditionally I've had to go from a json format to java (with libraries like jackson), and then go from java to sql using things like Hibernate or DAO patterns, which while not rocket science, creates lines of boilerplate code that need to be maintained.  With MEAN I wrote remarkably little code to get what I needed, since I was just storing and retrieving a document from Mongo.  Each of my routes were just a handful of lines of code. Here's a taste of the entirety of the server code to update the workout:

Strength Tracker Update Code

Angular Having data binding cooked in saved time

With Angular, you bind your widget directly to the model, so that your screen updates whenever you change your model, and vice versa.  I've built this into apps before, but having this natively cooked into the framework saved lots of time and code, and worked nicely for the strength tracker app.  There's no save button implemented, so whenever the user updates data onscreen, the save happens in the background and the chart dynamically updates.  This was all done with very little code.

What's Left?

My plan is to put the app out publicly where folks could use it or just play, but I wanted to add a couple of twists before getting it there. Of course getting an app working is usually the easy part - the bear is the last 20%.

  • Multi-User support and authentication
  • Add rep tracking as a choice in addition to 1RM (for things like situps and pull ups)
  • Add Integration tests using protractor
  • Nicer error handling
  • Add some additional styling
  • Do some testing/work so that it works nicely on mobile
  • Deploy it
    Overall, I was impressed with how little code the MEAN stack required me to code to get my site going.  Also, I didn't run into any perplexing issues (though the complexity level of what I was doing was relatively low).  Things were pretty straightforward, and I got things up and going with a fair amount of ease.  The solution hit two biggies for me: low amounts of boilerplate code, and nice testability.  I wouldn't mind creating more stuff with it, though I have some other options I'm itching to try first.