Angular Rails Rails 5

Get Started with Angular 4 and Rails 5

This guide will walk you through creating just about the simplest Angular + Rails application possible.

We’re going to create an Angular app, then create a Rails app, then get the two to talk to each other. It should only take a few minutes. Here are the steps:

Get set up

Get an Angular app initialized and running

The app we’re going to create is a pretend app called Home Library that exists for the purpose of organizing one’s private book collection.

We’ll be using the Angular CLI (command-line interface) to create the Angular app. Before we can do anything else, we need to install Angular CLI.

(If you don’t have NPM installed, you need to install that before installing Angular CLI.)

The Angular app and the Rails app will sit side-by-side in a directory. We’ll call this getting_started although you could call it anything you’d like.

This is the command to initialize the Angular app:

Once this command finishes, cd into home-library and run ng serve.

Free Guide

Getting Started with Angular and Rails

Get an Angular/Rails app up and running in as little as 20 minutes

You should be able to visit http://localhost:4200 and see a screen that looks like this:

Initialize a Rails app

Now, in a separate terminal, create the Rails app and then create its database. (The –api flag means this will be an API-only Rails app.)

Prepare some data

Create a resource in the Rails app

Since our “Home Library” app is oriented around books, let’s create a resource called Book.

Add some data to the Rails app

Let’s put a couple books in a seed file so we have some data to work with.

Connect Angular with Rails

Run the Rails server

In order for Angular to talk to Rails, the Rails server of course has to be running. Let’s start the Rails server.

You should see the good old “Yay! You’re on Rails” screen.

And if you visit http://localhost:3000/books.json, you should see the list of books we just created.

Enable CORS so the Angular app can talk to the Rails app

There is a small amount of plumbing work involved to get our Angular and Rails app working. We need to enable CORS (cross-origin resource sharing).

Don’t worry if you’re not familiar with that term. In plain English, we have to tell Rails that it’s okay to let outside apps talk to it.

The first step is to uncomment rack-cors in the Gemfile.

Then make config/initializers/cors.rb look like this:

And remember to restart the Rails server after you do that.

Get Angular to talk to Rails

We’re almost done. One of the last steps is to add an HTTP request from the Angular app to the Rails app.

Modify src/app/app.component.ts to look like this:

This will handle getting the data from the Rails server. Now we need to show it on the page.

Show the data from Rails inside the Angular app

Modify src/app/app.component.html to look like this:

Now, if you refresh the page at http://localhost:4200, you should see our two books on the page:

Congratulations. You’re now in possession of an Angular app that talks to a Rails app.

Did you find this tutorial useful? You can get a more comprehensive guide to building an Angular/Rails app with my book, Angular for Rails Developers.

About the author

Jason Swett

53 Comments

Click here to post a comment

  • Is there solution to host Angular on Rails so we don`t need two hostings? And it is good solution or better separate app with api?

    • Regarding separating the Angular app and Rails app, you could do that or you could keep Angular in the asset pipeline. I don’t think there’s a “better” way since it depends on your particular situation. Regarding the hosting, I’m afraid I don’t understand the question, sorry.

      • Hey Sung, thanks for the comment and link. You may be interested to see my deployment post which shoes how to deploy an Angular/Rails app using one single repository and server. One repo/server is my default way of using Angular and Rails together. My solution doesn’t require a separate deployment branch.

  • Jason, great job! This is a wonderful tutorial. However, I did this step by step but Angular isn’t reporting the JSON requests. The site shows up but not the actual data from the Rails API. Anyway I could debug this?

    [1] 16.04.21 14:31:54 200 GET /app/heroes.component.js
    [1] 16.04.21 14:31:54 200 GET /app/dashboard.component.js
    [1] 16.04.21 14:31:54 200 GET /app/hero-detail.component.js
    [1] 16.04.21 14:31:55 304 GET /app/app.component.css
    [1] 16.04.21 14:31:55 200 GET /app/hero.js
    [1] 16.04.21 14:31:55 304 GET /app/heroes.component.html
    [1] 16.04.21 14:31:55 304 GET /app/heroes.component.css
    [1] 16.04.21 14:31:55 304 GET /app/hero-detail.component.html
    [1] 16.04.21 14:31:55 304 GET /app/app.component.css
    [1] 16.04.21 14:31:55 304 GET /app/dashboard.component.html
    [1] 16.04.21 14:31:55 304 GET /app/dashboard.component.css

    It seems that everything responds with a 200 GET except the CSS and HTML

    [{“id”:1,”name”:”Jason”},{“id”:2,”name”:”Tim”},{“id”:3,”name”:”Zach”},{“id”:4,”name”:”Matt”}]

    Rails JSON at localhost:3001/heros.json

    Started GET “/heros.json” for 127.0.0.1 at 2016-04-21 14:31:55 -0500
    Processing by HerosController#index as JSON
    Hero Load (0.2ms) SELECT “heros”.* FROM “heros”
    [active_model_serializers] Rendered ActiveModel::Serializer::CollectionSerializer with ActiveModelSerializers::Adapter::Attributes (0.35ms)
    Completed 200 OK in 2ms (Views: 1.6ms | ActiveRecord: 0.2ms)

    And obviously plenty of these bad boys.

    • Thanks! As for debugging this, I would recommend putting up a StackOverflow question and then sending me the link. I have some questions about your situation but a) it would be tough to discuss it here, and b) if you put it on SO, others can comment/benefit too.

      • Actually, I already did. Here you go,

        getHeroes() {
        this._heroService.getHeroes()
        .subscribe(response => this.heroes = response.json().heros);
        }

        Remove the .heros at the end of the response.json().heros

        Add into your tutorial that they need to gem install ‘rack-cors’ and ‘rack-attack’ and setup an initializer called rack_attack.rb then to add
        config.middleware.use Rack::Attack
        config.middleware.insert_before 0, “Rack::Cors” do
        allow do
        origins ‘*’
        resource ‘*’, :headers => :any, :methods => [:get, :post, :options]
        end
        end

        into their application.rb

        class Rack::Attack

        # Rack::Attack is configured to use the Rails.cache value by default,
        # but you can override that by setting the Rack::Attack.cache.store value
        Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new

        # Allow all local traffic
        whitelist(‘allow-localhost’) do |req|
        ‘127.0.0.1’ == req.ip || ‘::1’ == req.ip
        end

        # Allow an IP address to make 5 requests every 5 seconds
        throttle(‘req/ip’, limit: 5, period: 5) do |req|
        req.ip
        end

        # Send the following response to throttled clients
        self.throttled_response = ->(env) {
        retry_after = (env[‘rack.attack.match_data’] || {})[:period]
        [
        429,
        {‘Content-Type’ => ‘application/json’, ‘Retry-After’ => retry_after.to_s},
        [{error: “Throttle limit reached. Retry later.”}.to_json]
        ]
        }
        end

        into the rack_attack.rb

        Then it should be good to go. The problem was the extra .heros at the end of response.json().heros. Then you come into the issue of CORS so obviously you have set that up. Thanks again dude.

  • The only other thing that needs to be updated for angular2 2.0.0 final is that the HTTP_PROVIDERS line needs to be removed from app/main.ts.

  • Let’s say I want to deploy this whole (both Angular & Rails) project on DigitalOcean. Should I have to deploy both projects individually or I should put the angular project to Rails public directory and then config nginx accordingly?

    • That can depend on a number of factors including, especially, how big your team is and whether you have dedicated front-end and back-end developers. For me personally, I’m often working solo on a project, so the “integrated” approach makes more sense for me. It’s also kind of a taste/preference question too.

  • Great tutorial. I have a question though. Isn’t it better to use rails-api gem instead of creating the rails project? Does it make a difference or this is the better approach than rails-api?

    • Thanks! For Rails 4, I would definitely advocate the Rails::API gem. For Rails 5, you can use the –api-only flag when creating a new project which will give you basically the same thing that you get when you use Rails::API.

  • nice tutorial sir im new in angular2, and kind confuse since HTTP-PROVIDERS is depecated and become httpModule, do you have a plan to update your tutorial into final release of angular2, I hope you do thanks

  • Hello Jason, i am having difficulty setting up my angular app when i use the command npm install -g angular-cli. please i any help. this is the error i get is pasted below.

    npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules/angular-cli/node_modules/chokidar/node_modules/fsevents):
    npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.0.17: wanted {“os”:”darwin”,”arch”:”any”} (current: {“os”:”linux”,”arch”:”x64″})
    npm WARN @angular/core@2.4.6 requires a peer of rxjs@^5.0.1 but none was installed.
    npm ERR! Linux 4.4.0-59-generic
    npm ERR! argv “/usr/bin/nodejs” “/usr/bin/npm” “install” “-g” “angular-cli”
    npm ERR! node v7.5.0
    npm ERR! npm v4.1.2
    npm ERR! path /usr/lib/node_modules
    npm ERR! code EACCES
    npm ERR! errno -13
    npm ERR! syscall access

    npm ERR! Error: EACCES: permission denied, access ‘/usr/lib/node_modules’
    npm ERR! { Error: EACCES: permission denied, access ‘/usr/lib/node_modules’
    npm ERR! errno: -13,
    npm ERR! code: ‘EACCES’,
    npm ERR! syscall: ‘access’,
    npm ERR! path: ‘/usr/lib/node_modules’ }
    npm ERR!
    npm ERR! Please try running this command again as root/Administrator.

    npm ERR! Please include the following file with any support request:
    npm ERR! /home/richard/npm-debug.log

  • Great tutorial! Just wondering, if I wanted to build of the rest of the CRUD operations, where would I go about doing so in the Angular app?

    • Thanks! That’s a long answer, one that I’ve been meaning to write up in a series of blog posts for a while. I guess the best thing I can say in one sentence is to create a component that houses a form, and then make that component trigger some HTTP requests to the server that save/update your resource. If you want more info, the best place to go right now is my book. Sorry I can’t be more helpful – it really is a pretty involved thing that can’t be described very briefly.

  • Hi, Jason!
    I have one problem with routing…
    My angular project is inside the public folder of the rails app. When I’m trying to get URL with param, for example, ‘example.com/post/1’, I can’t open a page, but I have a router in the angular app. Maybe you know how to resolve this problem?

    • If you put up a Stack Overflow question with more details (e.g. what exactly happens when you try to navigate to example.com/post/1?) and share a link, I can take a look.

  • Looking at the videos the last one about adding Twitter Bootstrap. From my understanding Twitter Bootstrap is not needed anymore with Angular, as it is integrated with https://angular-ui.github.io/bootstrap/ .

    Also isn’t it a mess to have both JQuery from Twitter Bootstrap and Angular manipulate the DOM?

    If I get the corporate package. Are there any support guaranteed if I run into an issue when building the CRUD from the book?

    • Hey Sha, good questions. I’m adding Twitter Bootstrap the way I am because that’s the way the Angular CLI docs said to do it. But I think you’re right that it’s kind of weird to have both Angular and jQuery present in the project. I’ll look into other ways to include Bootstrap. I’m familiar with the library you linked, and maybe that’s a good option.

      To answer your other question, yes, the corporate package does include support.

      • That would be great. vuejs have the vue-strap project, but it is only for AngularJS and Bootstrap 3, and being depended on a 3rd party component that is that important seams wrong somehow. Even if it were up to date 🙂

        Maybe this is a stupid question, but when would I want to include Twitter Bootstrap? Is the Angular Bootstrap WIP or won’t they support the whole Bootstrap?

        Very nice about the corporate support. When I go to my boss, what can I say about the support?

        Is it for a period?
        How many support cases?
        Who will handle them?
        Is it by email?
        What is the response time?
        Does it cover the rails/angular project I want to make?

        • Good questions. I think part of the reason Angular CLI recommended including Bootstrap the way they did is because I understand AngularUI was developed for Angular 1.x and isn’t ready for Angular 2+ yet.

          Regarding support, the Corporate Package comes with an hour of support over Skype (normally $150/hr). We would just schedule a time to talk whenever it’s convenient for both of us.

          I also offer free support (no matter which product tier you buy, or even if you don’t buy anything at all) over email although it’s not guaranteed that I’ll be able to respond. The most effective way to get free support from me is to create a Stack Overflow question and then send me the link. That way you’re not depending on only me for support.

          Also, anyone can buy as much support as they want for $150/hr and I also do team training sessions (both online and onsite), although the pricing for training works differently.

          Does that answer your questions?

  • Great tutorial! But don’t forget to include import { HttpModule } from ‘@angular/http’; and add HttpModule to imports array in @NgModule in app.module.ts to make the app work =)

      • Here is app.component.ts:

        import { Component } from ‘@angular/core’;
        import { Http } from ‘@angular/http’;

        @Component({
        selector: ‘app-root’,
        templateUrl: ‘./app.component.html’,
        styleUrls: [‘./app.component.css’]
        })
        export class AppComponent {
        title = ‘app’;
        books;

        constructor(private http: Http) {
        http.get(‘http://localhost:3000/books.json’).subscribe(res => this.books = res.json());
        }
        }

        and app.module.ts:

        import { BrowserModule } from ‘@angular/platform-browser’;
        import { NgModule } from ‘@angular/core’;
        import { HttpModule } from ‘@angular/http’;

        import { AppComponent } from ‘./app.component’;

        @NgModule({
        declarations: [
        AppComponent
        ],
        imports: [
        BrowserModule,
        HttpModule
        ],
        providers: [],
        bootstrap: [AppComponent]
        })
        export class AppModule { }

Free Guide: Getting Started with Angular and Rails

Learn More