My First Experience with AngularJS and Rails 5

tutorial

Hi Everyone! My name is Dakota Lee Martinez. Over the last year or so, I’ve been working on the Flatiron School’s Full Stack Web Developer course. I’ve just completed the final project, a full stack web application built with AngularJS and Rails. I’m super excited to share my experience building the app with you all over the next series of posts.

About My Project

For this project, I wanted to pick something I’m passionate about and something that I would actually use. I remember when I first was exposed to code snippets. When I watched a few of Jeffrey Way’s laracasts, I was hooked. If you’re not familiar with custom code snippets, the idea is that you can write a code template for accomplishing a certain task. You give your snippet a trigger phrase. When you type this phrase the phrase expands into your template.

If this were all it could do, it would still be really cool. But, there’s more!!! You can add variables to your template, allowing you to type in a value and have it appear in multiple places within the template. This kind of thing is very useful for variable or function names. Even better, you can cycle through these variables within the snippet by hitting the tab key. This allows you to avoid spending time and keystrokes referencing library specific syntax for a task you’ve already done a lot of times and skip right to adjusting the values that are specific to your particular application.

Working with code snippets is an absolute joy and well worth the effort of building up a library of code that you like to reuse. One of the problems with code snippets is that they’re often written in a different syntax than the code itself. They also need to be placed within a certain directory to work. These are small issues, but they definitely raise the barrier to entry. Also, snippets for one editor are unlikely to work in another. Enter SnippetMachine!

SnippetMachine – Taking the Pain out of Creating Custom Snippets

By integrating with the Dropbox API, SnippetMachine allows you to sync your snippets with your Dropbox. After creating a symlink between your dropbox snippets and the appropriate directory on your computer, you can save snippets for use within your editor of choice directly from SnippetMachine. Current editor support is for Visual Studio Code and Sublime Text 2, but adding more editors to the existing system is not terribly complicated and I will do so as requests come in (I also welcome pull requests!).

If you are interested in contributing, I’ve added a detailed guide to the CONTRIBUTING.md file on my github repository that will give you a quick overview of the project and how it is structured.

The process of building SnippetMachine was very rewarding. But, it was also quite frustrating at times. I had quite a bit of trouble getting a good development environment set up (I ended up using a gemset for Rails 5.0 and the gulp-angular yeoman generator for the Angular side). I had quite a time putting together an automated deployment script so I can deploy the app to webfaction shared hosting using git push deployment master. I also ran into problems getting devise_token_auth and ng-token-auth working together to allow for token based authentication. I spent more time than I would have liked getting the Dropbox API integration up and running, and was frustrated when trying to get the omniauth-dropbox and dropbox-api gems to work together (I ended up choosing to forego using omniauth-dropbox and using dropbox-api exclusively).

What I learned about AngularJS and Rails while building SnippetMachine

I am a big believer in project based learning. I think that the most important learning moments come when solving real problems. So, I relish the opportunity to build these projects and I’m very excited to share with you some of the things that I’ve learned along the way.

In the following series of posts, we’ll be putting together a long-form tutorial of how to build a full stack web app using AngularJS and Rails. Here is a preliminary list of the topics we’ll be covering as we walk through how to build SnippetMachine. (we’ll be making use of some of my snippets to do so!)

  • How to set up a development environment for AngularJS and Rails 5 (Angular 1.5.3 is the version we’ll be using)
  • How to use devise_token_auth and ng-token-auth to add authentication to your app using Angular JS and Rails
  • How to setup automated deployment for Ruby on Rails to Webfaction shared hosting
  • How to build out the domain model (Users, Snippets, UserSnippets & Languages)
  • How to add seed data using FactoryGirl
  • How to interact with our Rails API using AngularJS Services and $http
  • How to build out a component based application architecture in AngularJS 1.5.x using UI Router
  • How to use Angular Filters to display snippets in different editor formats
  • How to add nested states using nested component routes within UI-Router
  • How to add components that display the same form (using the same template) for editing and creating new snippets
  • How to add Dropbox API integration to your app using AngularJS and Rails
  • How to create new files in a User’s dropbox account based on data taken from the web application.
  • How to create custom directives to validate input fields in AngularJS
  • How to cache promises returned from AngularJS services to avoid redundant calls to the database

Organizing a Project using AngularJS and Rails

There are two main choices when it comes to organizing a site that uses both AngularJS and Rails. First, we could organize our project inside of the Rails Asset pipeline, along the lines of this tutorial. Second, we could organize our project in a client directory and manage our front end assets separately, the manner recommended in this tutorial.

For SnippetMachine, I chose to organize the project with a separate client directory as outlined in the second tutorial by Jason Swett. The reason I preferred this way is that it allows for a tighter integration with the javascript ecosystem (npm). It also allows us to structure the Angular app in a way that is much more back-end agnostic. I think this is really important because it ensures that the time we spend working in Angular can be focused on doing things the Angular way, not the Rails-Angular way.

One of the interesting challenges that comes from taking this approach is deciding where certain features should be implemented. For instance, when it came time to implement the Dropbox API integration, I had a choice between whether to hook it up in Ruby or JavaScript. In that case, it made more sense to hook it up on the server side in Ruby. The reason I chose to do it on the server side is that there really isn’t a secure way of keeping the API key and credentials private when connecting via a client side app.

Meanwhile, when it came to formatting the snippets for different editors, it actually made sense to do this differently depending on the purpose. When I was preparing the contents of files to be saved to a user’s dropbox, I did the formatting on the server side. But, when I just wanted to display the formatting to the user, I used an Angular Filter on the client side. I feel like having a separate directory and ecosystem for the Angular app helps keep the idea of separation of concerns in proper perspective.

Snippet Machine New Snippet Form with Views for different Editor Formats

What I’ll be Doing Differently When I Rebuild SnippetMachine for this Tutorial

As I mentioned earlier, there were parts of this process that were painful to push through the first time. I’m hoping that in putting together this tutorial, I’ll be able to resolve many of those pain points as we go along. In particular, there are four things that I will be doing differently when I rebuild the application.

First, I realized after working for a bit that I actually needed another resource in my domain model. I wanted users to be able to add other user’s snippets to their account. Originally, I was thinking about some sort of a ‘forking’ where a user could create a snippet based on another user’s snippet. After some more thought, I realized that this meant that every time a user wanted to add another user’s snippet to their account, another row in the snippets table would have to be created. I only want another snippet to be created if there’s an actual modification occurring. So, what I did was to add a UserSnippet resource that is a join model for users and snippets. Quite a bit of refactoring went into making this transition, so when we go through the project together, I’m going to build the domain model that way from the start.

Second, because we’ll be building the domain model earlier on in the process, I’m going to handle authentication with devise_token_auth and ng-token-auth earlier on in the process. At least, I’ll be running rails g devise_token_auth:install earlier on in the process so that our domain model can be set up properly before we start getting deep into the client side of the app.

Third, I started out having a language column in the snippets table to hold a string representing the language the snippet was for. I discovered when I had built out the form to create new snippets in Angular that I was going to need some way of validating that snippet languages were actual supported languages for the supported editors. In order to do that, I realized that it would be better to create a Language model so that I could validate language names on the server side and also ensure that duplicate languages were not created. But, perhaps the most important reason to treat language as a resource is that doing so allows us to create a has_many <-> belongs_to relationship between languages and snippets. For example, this turns about to be very important later on when saving all of a user’s snippets written in JavaScript.

Fourth, in preparation for the transition to Angular 2, which was officially released during my work on this project, I’ve refactored all of my controllers into components. Controllers only exist as members of components and directives in Angular 2, so this should make the code much easier to transition when the time comes. When I go through rebuilding the application, we’ll start out building the app as a collection of components.

What to Expect out of this Series of Tutorials on AngularJS and Rails

If you’re not already addicted to using code snippets, I would honestly be shocked if you aren’t after working along with me as we rebuild this application. We’ll definitely be developing an appreciation for code snippets as we go through building this app. If you’re comfortable with rails and you have some experience with AngularJS, you should be able to follow along with me without too much trouble.

One of the main goals I have for this series is to come out of it with a much better understanding of what I’ve accomplished so far with SnippetMachine. I’ve found that going through the act of actually explaining and outlining the process of implementing these features and building a full-fledged application step by step is an incredible learning experience. It’s really amazing how many things we think we understand until we try to explain them to someone else!

IMPORTANT NOTE: I’ll be using AngularJS v1.5.3 and Rails v5.0.0.1 for this tutorial. AngularJS v1.5.8 is currently available, but v1.5.3 is the newest version officially supported by the ng-token-auth module that we’re using for authentication.

My goal is to put together a thorough guide to getting started with AngularJS and Rails. If I’m successful, you’ll have a series of tutorials that will allow you to hook up and work with AngularJS and Rails in a way that is significantly less painful than it was for me the first time.

By the end of this tutorial, you should have a good sense of some of the issues that come up when building a web application with AngularJS and Rails. I’m particularly excited about walking you through how to set up a nice development environment for AngularJS and Rails with npm, gulp, bower and browsersync. Another post I’m psyched about is the one on how to set up an automated build on deployment. The integration with the Dropbox API and all you can do with that should be a really fun part of the series as well.

Final Thoughts

I have had an absolutely fantastic time learning Full Stack Web Development at the Flatiron School. I cannot recommend the program highly enough. I have developed a sense of confidence in my abilities to solve problems and continuously improve my skills. It has been an exceedingly wonderful experience and I really look forward to sharing the things that I’ve learned with the community.

Yours Truly,

Dakota Lee Martinez

P.S. Stay tuned for the first tutorial next week!


Also published on Medium.

Leave a Reply

Your email address will not be published. Required fields are marked *