Integrating Rails with Angular : A Complete Guide

Total Blog Views: 91

Blog Status: publish

Created By: swaz_ahmed Created at: 02-14-2025

Tags: angular JavaScript rack-cors rails-api rails gem Rails Integration ruby-on-rails web app web development

Integrating Rails with Angular

Integrating Angular with Rails combines the strengths of both frameworks—Rails as a powerful backend API and Angular as a dynamic frontend for a seamless user experience. This guide walks you through setting up a Rails API backend and connecting it with an Angular frontend, ensuring smooth communication between the two.
 

Why Integrate Rails with Angular?

  1. Scalability – A separate frontend and backend make scaling easier.
  2. Efficient API Development – Rails provides a structured RESTful API.
  3. Rich UI Experience – Angular enables an interactive and dynamic user interface
     

Prerequisites

Before starting, ensure you have the following installed:

  • Ruby and Rails – To build the backend API.
  • Node.js and npm – Required to run Angular.
  • Angular CLI – For generating and managing Angular applications efficiently.
     

Setting Up the Rails Backend

Step 1: Create a Rails API

To get started with the backend, create a new Rails application configured as an API:

rails new my_app --api -T
cd my_app
  • --api: Configures Rails for API-only mode.
  • -T: Skips Test::Unit files (optional).


Step 2: Set Up CORS

Since Angular runs on a different port during development, we need to allow cross-origin requests. Add the rack-cors gem to your Gemfile:

gem 'rack-cors'

Run bundle install.

Then, configure CORS in config/initializers/cors.rb:

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*' # Change this to your Angular app's domain in production
    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

This code snippet is part of the CORS (Cross-Origin Resource Sharing) configuration for a Rails application. It is used to allow cross-origin requests, which are necessary when your Angular frontend is running on a different domain or port than your Rails API during development.

  • origins '*': This allows requests from any domain. In production, you should replace '*' with the domain of your Angular app for security reasons.
  • resource '*': This allows access to all resources in your API.
  • headers: :any: Specifies that any headers are allowed in the request.
  • methods: [...]: This defines which HTTP methods are allowed (GET, POST, PUT, DELETE, etc.).
     

Step 3: Generate a Scaffold

  To quickly create a basic API, run:

rails g scaffold Post title:string body:text
rails db:migrate

This will generate model, controller, and routes for handling Post data. Now, start the Rails server:

rails s

Your API is now running at http://localhost:3000/posts.


Setting Up the Angular Frontend

Step 1: Create an Angular App

Generate a new Angular application by running:

ng new my-angular-app
cd my-angular-app

This sets up a structured Angular project with TypeScript support.


Step 2: Generate Angular Components and Services

Generate a Post Component:

ng generate component post

Generate a PostService:

ng generate service post


Step 3: Set Up Angular HTTP Client

Import HttpClientModule in src/app/app.module.ts:

import { HttpClientModule } from '@angular/common/http';  
@NgModule({ imports: [ HttpClientModule ], // Enables HTTP requests  
bootstrap: [AppComponent],
}) export class AppModule {}


Step 4: Create the Post Service

Update src/app/post.service.ts to handle API interactions:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
@Injectable({
  providedIn: 'root',
})
export class PostService {
  private apiUrl = 'http://localhost:3000/posts'; // Rails API endpoint
  constructor(private http: HttpClient) {}
  // Fetch all posts
  getPosts(): Observable<any> {
    return this.http.get(this.apiUrl).pipe(
      catchError(error => {
        console.error('Error fetching posts', error);
        return throwError(error);
      })
    );
  }
  // Fetch a single post by ID
  getPost(id: number): Observable<any> {
    return this.http.get(`${this.apiUrl}/${id}`);
  }
  // Create a new post
  createPost(post: any): Observable<any> {
    return this.http.post(this.apiUrl, post);
  }
  // Update a post
  updatePost(id: number, post: any): Observable<any> {
    return this.http.put(`${this.apiUrl}/${id}`, post);
  }
  // Delete a post
  deletePost(id: number): Observable<any> {
    return this.http.delete(`${this.apiUrl}/${id}`);
  }
}

Key Features of this Service

  • Uses HttpClient for making API requests.
  • Implements error handling with catchError.
  • Provides CRUD (Create, Read, Update, Delete) methods for interacting with the Rails API.


Step 5: Update the Post Component

Fetch Posts in the Component

Modify src/app/post/post.component.ts:

import { Component, OnInit } from '@angular/core';
import { PostService } from '../post.service';
@Component({
  selector: 'app-post',
  templateUrl: './post.component.html',
  styleUrls: ['./post.component.css'],
})
export class PostComponent implements OnInit {
  posts: any[] = [];
  constructor(private postService: PostService) {}
  ngOnInit(): void {
    this.fetchPosts();
  }
  fetchPosts(): void {
    this.postService.getPosts().subscribe(
      (data) => {
        this.posts = data;
      },
      (error) => {
        console.error('Error fetching posts:', error);
      }
    );
  }
}

This Angular component, PostComponent, fetches and displays a list of posts from a backend API using PostService.

  • ngOnInit(): Calls fetchPosts() when the component initializes.
  • fetchPosts(): Retrieves post data via PostService and handles errors.
  • Dependency Injection: Injects PostService to interact with the backend.
  • Template & Styles: Uses post.component.html and post.component.css for UI.
     

Display Posts in the Template:
Open src/app/post/post.component.html and add the following:

<h1>Posts</h1>
<div *ngFor="let post of posts">
  <h2>{{ post.title }}</h2>
  <p>{{ post.body }}</p>
  <hr />
</div>


Step 6: Configure Routing
Update app-routing.module.ts:

Open src/app/app-routing.module.ts and add a route for the PostComponent:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { PostComponent } from './post/post.component';
const routes: Routes = [
  { path: 'posts', component: PostComponent },
  { path: '', redirectTo: '/posts', pathMatch: 'full' }, // Default route
];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

Add Router Outlet to app.component.html:

Open src/app/app.component.html and replace its content with:

<router-outlet></router-outlet>


Step 7: Test the Integration
Start the Rails Server:

Ensure your Rails server is running:

rails server

Start the Angular Development Server:

Run the Angular app:

ng serve

Visit the Angular App:

Open your browser and navigate to http://localhost:4200/posts.You should see the list of posts fetched from the Rails API.
 

Conclusion : 
By integrating Rails with Angular, we have created a structured and scalable full-stack web application. Rails efficiently handles data storage and business logic, while Angular provides a dynamic and interactive user experience. RESTful communication is enabled through Angular's HttpClient, ensuring seamless data exchange with the backend. Proper CORS configuration allows secure cross-origin requests, and error handling prevents crashes, improving application stability. This setup forms a strong foundation for future enhancements like authentication and real-time updates.


swaz_ahmed

I am swaz_ahmed blogger on shadbox. I am influencer,content writer,author and publisher. Feel free to ask me any question and suggestions.



Comments



Buy traffic for your website

About Shadbox

we have the “Get things executed” lifestyle at our place of work. There are not any excuses, no if’s or however’s in our dictionary. committed to navigating the ship of creativity to create cell answers, we resolve the real-lifestyles troubles of our clients and their clients. Our passion for work has won us many awards, year after 12 months.

Services

Downloads