Steven Brooks' Blog

Student @Flatiron School

Angular on Rails

This post will show a step by step tutorial of how to create a rails app with Angular.js on the front-end and allow you to successfully create an object and view those objects.

First, lets create the rails app

rails new angular

After you cd into the app, we are going to create a resource for the model we are going to have. A resource will provide you with the model, an empty controller, a views folder with no views, and resourced routes for that model. Close to scaffolding but not really. Lets make a user model and give it a name:

rails g resource user name

and don’t forget to migrate the database.

rake db:migrate

Next we have to create a controller with just an index action because the entire app will take place in that single action. Lets call the controller home.

rails g controller home index

Next we have to remove the public/index.html file and make sure to add the home#index route as your root route:

root :to => “home#index”

Remember that empty user controller? We have to go back to it now and create the RESTful data source for our app to interact with. It’s really not too too crazy. For the purposed of this app we are only going to have an index action and a create action:

(AngularController.rb) download
1
2
3
4
5
6
7
8
9
10
11
class UsersController < ApplicationController
  respond_to :json

  def index
    respond_with User.all
  end

  def create
    respond_with User.create(params[:user])
  end
end

Now we need to add Angular.js to the app. In your Gemfile, and in the assets group, we need to add the Angular.js gem:

gem ‘angularjs-rails’

And in our application.js file, we need to add the following lines:

//= require angular
//= require angular-resource

Awesome, were doing pretty well thus far. Next we have to tell our app “Hey, you need to be in Angular.js”, so go over to your application layout file and look for your html tag. We need to add something to this tag to tell the app it’s going to be in Angular. For this we do the following:

html ng-app

This directive is used to flag the html element and tell it that Angular should be considered the root element of our application. You can add a directive like this to other elements in your app if you wish to not have the entire app be Angular.

That is your basic setup. We have Angular in our app and our html elements is ready.

Now we have a view. I’m going to show the view and then talk about whats going on here:

(angularview.html) download
1
2
3
4
5
6
7
8
9
10
11
12
<div ng-controller="UserController">
  <ul>
    <li ng-repeat="user is users">
      {{ user.name }}
    </li>
  </ul>
  <form>
    <input type="text" ng-model="newUser.name" placeholder="name">
    <button ng-click="addUser()">Add User</button><br>
    <span>{{newUser.name}}</span>
  </form>
</div>

At the top of the view we have:

div ng-controller=“UserController”

Eventually, we will create an Angular controller, and what we are doing here is saying, “Anything in this div refers to the UserController”. We are then creating a list, and each list item has the following code attached:

li ng-repeat=“user in users”

Eventually, we will have an array of users, and ng-repeat is a way to iterate through the array. And then we simply list the users names.

Next we have a form with an input field. This input field has:

ng-model=“newUser.name”

This ng-model is almost like a variable in that we will be setting this ng-model to whatever we put in the input field.

Then we have a button that has:

ng-click=“addUser()”

We are attaching ng-click to the button and that will run an addUser function that we will have to create. In the span element, you will see a double binded value of the input field. When you are typing in text to the input field, it will show here. It’s more of a cool thing to have than necessary. Now all we need is that angular controller.

(angularmodule.js) download
1
2
3
4
5
6
7
8
9
10
11
12
angular.module("User", ["ngResource"])

function UserController($scope, $resource) {
  User = $resource("/users.json")
    $scope.users = User.query();

  $scope.addUser = function() {
    entry = User.save({name:$scope.newUser.name})
    $scope.users.push(entry);
    $scope.newUser.name = ';'
  };
}

At the top, we create a module which we call “User”. Going back to our layout file, we need to add this module to our directive. That html element will now look like this:

html ng-app=“User”

To create a controller in Angular is like creating a javascript class, with a function. We create it by adding in a scope. A scope is an object that refers to the application model, kinda like self in ruby or this in javascript, but also not really.

In order to set our array, remember its called users in the view, we have to find a way to get that data of users from the database. Remember when we added angular-resource to the application.js file, and remember when we added ngResource to our module? We did this to set up Angular resource which allows you to interact with restful server side data source (our user controller in railsland).

In that first line we are saying, set the User variable to all the objects at the route “/users.json”. The reason we cannot simply give the route of “/users” is because the return html and not json. In the next line we set the scope.users to User.query(). The query function allows you to GET an array.

Awesome now all we want to do is add users to that array. In the view, the button had an ng-click=“addUser()” on it. We needed to create that function and we do it here. Here we are getting the input from the form field with an ng-model of newUser.name and saving it to the object. In angular, the .save method is used to create an object and not update it. Then all we do is push that entry into the users array that we set above and set the input field to blank.

Now we can create an object and get an array of objects in a rails app that utilizes Angular.js on the client side.