Getting Ready to Eat My Own Angular Dogfood

For the last several months, I have been expanding on my knowledge of JavaScript by focusing my learning on AngularJS. While in theory Ruby on Rails is to Ruby as AngularJS is to JavaScript, learning and programming with Angular seemed unlike any other framework I’ve worked with. In learning Ruby on Rails and Sinatra, utilizing a Model-View-Controller design pattern, emphasis on separation of concerns is placed between how the data is presented (view), the data and the logic around it (model), and coordinating the interactions between the view and model via controller. With Angular, however, a Model-View-ViewModel paradigm is implemented where on one side we have the data and logic (model), on the other side we have the presentation (views) and then we have a go between that isn’t completely separate from the model or the view. As a result, this tightly couples both HTML and JavaScript elements together where what looks like a custom HTML tag, once interpreted by Angular, takes on its own form and purpose.


I utilized my newfound knowledge of Angular, along with my knowledge of the backend-related components of Ruby on Rails (model and controller) to build an app to keep track of my upcoming job search. Track My Calling allows one or more individuals to maintain accounts in which they can can create job tracking records. Each job record stores basic information such as the name of the job, title, company, job description, salary, and a link to the application URL. A user can also maintain the status of the job is in the lifecycle from “Discovered” to “Applied” to “Pending Interview”, and hopefully “Job Offer Accepted.” A user can also record Notes on a given job such as details on communications with the company. Due to the sensitivity and privacy around the information gathered and maintained during a job search, an individual user only has access to the jobs (and notes) they created themselves.

Click below to view the routing using ui-router


Track My Calling is built as a Single-Page Application (SPA) in that when a user is interacting with the Angular front-end of the application which displays existing job information, forms to create and edit job or note records, and filtering the job records, occurs without the page performing a reload. Any operations generating CRUD transaction requests are sent between Angular and the Ruby on Rails backend via JSON GET and POST requests through RESTful conventions. The response(s) are subsequently returned to Angular in JSON format and the view is updated accordingly. I utilized one controller for each of my models (jobs, notes, users) which assisted in coordinating the user’s actions with the data that was being requested or submitted, meanwhile a factory (service) for each of the jobs and notes models handled the GET and POST requests and returned a promise to the controller to be rendered back to the user. Rails assisted in the authentication process (with the user model implementing the Devise ruby gem) to register a new user or authenticate an existing one. Consequently, the “view” component of the MVC Rails paradigm is used only to load the initial page when a user visits the site.


For most of my previous projects, I had utilized Bootstrap for my front-end design. However, since Angular is maintained by Google, it felt fitting to use their Material design and the “Angular Material” provider service that is available for Angular applications for the Track My Calling design. This was more of a challenge than I anticipated. As Angular Material (ngMaterial) is injected into the appliciation, the framework implements the same Angular constructs of components/directives to create Material-like objects such as cards, buttons, and lists, to change the theme color, or to display a pop-up window. ngMaterial also works with additional non-core, yet extremely useful Angular modules like ngMessages and ngAria to properly implement those elements. ngMessages allows for the standardization of displaying messages in a given template, and in the case of this project, I utilized the module, to display error messages generated when validating user inputted information. The ngAria module assists in adding accessibility information to the components rendered by Angular, by attaching aria-* data attributes to tags including those related to forms and input. Ultimately, I believe working ngMaterial into my application helped to further solidify my knowledge of AngularJS.


One piece of functionality that I was most proud of building was the ability to change the status of a job on its detail page via a dropdown without having to view the separate Job Edit page. Since this “field” was contained within a directive consisting of the other job data elements, I created a function within my JobController and JobFactory to communicate the update to the Rails backend, and utilized a function binding in the scope of my JobController, where given a job id number and the new status, a PATCH (update) request is sent to the Rails #update route, yet only this one field is modified. This code was also refactored where rather than hard coding the option labels and values in the HTML of the page, I created a variable holding an array of key, value pairs that could be referenced whenever the Job Status attribute was required (in the New Job, Edit Job, and Job Listing filter) as well.


Now as I wrap up the initial version of this Angular app, my final project as part of the curriculum, I look forward to “eating my own dogfood” and utilizing Track My Calling as I begin my job search for a position as a web developer. I invite you to try it and use it for your job search as well and let me know your thoughts! At the time of this writing it is hosted on Heroku at . You can also clone it from the github repo below. **As I consider the application a work in progress, I recommend keeping a separate backup of your information as well.**

Originally published at Michael’s WebDev Blog.