This is the fifth and final part in a series of blog posts about building a real-time SMS and voice voting application using Node.js and TwiML. I began working on this application during some downtime at a Startup Weekend event back in the summer of 2012. It was both an excuse to learn Node and build a reusable app for something that my team is often asked to provide at events (SMS voting). Let’s take a moment and recap where we’ve been.

In part one, we created the Node application and captured incoming votes over SMS and stored them in a CouchDB. I chose to use Express as the web framework and Cloudant and my CouchDB provider.

In part two, we created a real-time visualization of the voting using Socket.io and Highcharts. As votes came in a bar chart depicting the current state of the vote would update in realtime. For my purposes (live SMS voting at events) this was my MVP product. But at larger events I ran into some nasty scaling issues.

In part three, we tweaked our app to scale to thousands of votes per second and millions of total votes. This was accomplished by being smarter about how we stored our documents and leveraging CouchDB’s map/reduce capabilities.

In part four we began adding an web front-end for admins using AngularJS. We added AngularJS to our project and implemented a login and logout flow. We walked through the process of using CouchDB’s cookie-based authentication scheme to bootstrap a simple log-in process for our app.

The last thing for us to do to complete this admin portion of the application is to use AngularJS to create a simple CRUD interface for the events in our CouchDB. We will focus on the AngularJS code and templates that we’re going to write to edit our event documents and finish with a brief run-through of the server-side code.

Listing Event Documents

If you go back and look at the configuration for our app in votr.js you’ll see that the root path (/) is associated with the event-list.html template and the EventListCtrl controller. Remember, this is the root path relative to where we mounted AngularJS. In our case we mounted our app at /admin. When the controller is instantiated, it issues a query to the EventService. The EventService is just like the SessionService; it’s a thin wrapper around a $resource object that points to the /api/events/:id endpoint on our Node app.