Consuming RESTful Web Services in Angular

Step 1: Create Angular App

C:\Users\Girish\AngularProjects>ng new my-rest-app
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? CSS
CREATE my-rest-app/angular.json (3633 bytes)
........

Step 2: Create Course List Component

C:\Users\Girish\AngularProjects\my-rest-app>ng g c course-list
CREATE src/app/course-list/course-list.component.html (26 bytes)
CREATE src/app/course-list/course-list.component.spec.ts (657 bytes)
CREATE src/app/course-list/course-list.component.ts (288 bytes)
CREATE src/app/course-list/course-list.component.css (0 bytes)
UPDATE src/app/app.module.ts (589 bytes)

Step 3: Create Add Course Component

C:\Users\Girish\AngularProjects\my-rest-app>ng g c add-course
CREATE src/app/add-course/add-course.component.html (25 bytes)
CREATE src/app/add-course/add-course.component.spec.ts (650 bytes)
CREATE src/app/add-course/add-course.component.ts (284 bytes)
CREATE src/app/add-course/add-course.component.css (0 bytes)
UPDATE src/app/app.module.ts (489 bytes)

Step 4: Create Service

C:\Users\Girish\AngularProjects\my-rest-app>ng g service course
CREATE src/app/course.service.spec.ts (333 bytes)
CREATE src/app/course.service.ts (135 bytes)

Step 5: Add Routes in app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AddCourseComponent } from './add-course/add-course.component';
import { CourseListComponent } from './course-list/course-list.component';
const routes: Routes = [
 
  { path: 'view-course', component: CourseListComponent },  
  { path: 'add-course', component: AddCourseComponent },  

];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Step 6: Create course.ts file

export class Course {

    course_id:number;  
    course_name:String;  
    course_fee:number;  
    course_duration:number;  
    course_author:String;  

}

Step 7: Update course.service.ts file as below

import { Injectable } from '@angular/core';

import { HttpClient, HttpHeaders } from '@angular/common/http';  
import { Observable } from 'rxjs';  
import { Course } from './course';  
 
@Injectable({
  providedIn: 'root'
})
export class CourseService {

  private baseUrl = 'http://localhost:8080/demo/';  

  constructor(private http:HttpClient) { }  
  
  getCourseList(): Observable<any> {  
    return this.http.get(`${this.baseUrl}`+'allcourses');  
  }  

  createCourse(course: Course): Observable<Course> {  
     return this.http.post<Course>('http://localhost:8080/demo/saveCourse', course   , {
      headers: new HttpHeaders({'Content-Type':'application/json'})
    }    
    )        
  }  

  deleteCourse(id: number): Observable<any> {  
    return this.http.delete(`${this.baseUrl}/deleteCourse/${id}`, { responseType: 'text' });  
  }  
  
  getCourse(id: number): Observable<Object> {  
    return this.http.get(`${this.baseUrl}/getcoursebyid/${id}`);  
  }  
  
  updateCourse(id: number, value: any): Observable<Object> {  
    return this.http.post(`${this.baseUrl}/update/${id}`, value);  
  }   
  
}

Step 8: Update app.module.ts file as below

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AddCourseComponent } from './add-course/add-course.component';
import { CourseListComponent } from './course-list/course-list.component';


import { FormsModule, ReactiveFormsModule } from '@angular/forms';  
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent,
    AddCourseComponent,
    CourseListComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule, FormsModule,  
    ReactiveFormsModule,  
    HttpClientModule 
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Step 9: Update index.html as below. Here Bootstrap CDN are added.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>MyRestApp</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

</head>
<body>
  <app-root></app-root>

  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  
</body>
</html>

Step 10: Update course-list.component.ts file as below

import { Component, OnInit, Input } from '@angular/core';

import { CourseService } from '../course.service';  
import { Course } from '../course';  
import { Observable,Subject } from "rxjs";  
import {FormControl,FormGroup,Validators} from '@angular/forms';  

@Component({
  selector: 'app-course-list',
  templateUrl: './course-list.component.html',
  styleUrls: ['./course-list.component.css']
})
export class CourseListComponent implements OnInit {

  constructor(private courseservice:CourseService) { }

  coursesArray: any[] = [];   
   
  dtTrigger: Subject<any>= new Subject();  
  
  courses: Observable<Course[]>;  
  course : Course=new Course();  
  deleteMessage=false; 

  courselist : any ;  
  isupdated = false;  

  @Input()   
  myvalue: number = 10;
  @Input()
  crid: number;
  @Input()
  cname : string;
  @Input()
  cfee: number;
  @Input()
  cduration:number;
  @Input()
  cauthor :string;
   
  ngOnInit() {  
    this.isupdated=false;  
    this.courseservice.getCourseList().subscribe(data =>{  
    this.courses =data;  
    this.dtTrigger.next();  
    })  
  }  
    
  deleteCourse(id: number) {  
    this.courseservice.deleteCourse(id)  
      .subscribe(  
        data => {  
          console.log(data);  
          this.deleteMessage=true;  
          this.courseservice.getCourseList().subscribe(data =>{  
            this.courses =data  
            })  
        },  
        error => console.log(error));  
  }  
  
  updateCourse(id: number){  
    this.courseservice.getCourse(id)  
      .subscribe(  
        data => {  
          this.courselist=data       
          console.log(this.courselist);
          this.myvalue=50;
          this.crid = this.courselist.course_id;
          this.cname = this.courselist.course_name;
          this.cduration = this.courselist.course_duration;
          this.cfee = this.courselist.course_fee;
          this.cauthor = this.courselist.course_author;
      
        },  
        error => console.log(error));  
  }   
  
  courseupdateform=new FormGroup({  
    course_id:new FormControl(),  
    course_name:new FormControl(),  
    course_duration:new FormControl(),  
    course_fee:new FormControl(),
    course_author:new FormControl(),
    course_test : new FormControl()
  });  
  
  updateCur(updcur){  
    this.course=new Course();   
   this.course.course_id=this.CourseId.value;  
   this.course.course_name=this.CourseName.value;  
   this.course.course_duration=this.CourseDuration.value;  
   this.course.course_fee=this.CourseFee.value;  
   this.course.course_author=this.CourseAuthor.value;  

   
   this.courseservice.updateCourse(this.CourseId.value, this.course).subscribe(  
    data => {       
      this.isupdated=true;  
      this.courseservice.getCourseList().subscribe(data =>{  
        this.courses =data  
        })  
    },  
    error => console.log(error));  
  }  
  
  get CourseName(){  
    return this.courseupdateform.get('course_name');  
  }  
  
  get CourseAuthor(){  
    return this.courseupdateform.get('course_author');  
  }  
  
  get CourseFee(){  
    return this.courseupdateform.get('course_fee');  
  }  
  
  get CourseId(){  
    return this.courseupdateform.get('course_id');  
  }  
  get CourseDuration(){  
    return this.courseupdateform.get('course_duration');  
  } 
  
  changeisUpdate(){  
    this.isupdated=false;  
  }  

}

Step 11: Update course-list.component.html as below

<div class="panel panel-default">  
    <div class="panel-heading">  
        <h1 style="text-align: center">Courses</h1><br>  
        <div class="row" [hidden]="!deleteMessage">  
               
                  <div class="col-sm-4"></div>  
                  <div class="col-sm-4">  
                          <div class="alert alert-info alert-dismissible">  
                                  <button type="button" class="close" data-dismiss="alert">×</button>  
                                  <strong>Course Data Deleted</strong>  
                          </div>  
                  </div>  
                  <div class="col-sm-4"></div>  
          </div>             
      </div>  
    
      
    <div class="panel-body">  
        <table  class="table table-hover table-sm"  >  
            <thead class="thead-light">  
                <tr>  
                    <th>Course Name</th>  
                    <th>Course Duration</th>  
                    <th>Course Fee</th>  
                    <th>Course Author</th>  
                    <th>Action</th>  
                   
                </tr>  
            </thead>  
            <tbody>  
                 <tr *ngFor="let course of courses "> 
                    <td>{{course.course_name}}</td>  
                    <td>{{course.course_duration}}</td>  
                    <td>{{course.course_fee}}</td>  
                    <td>{{course.course_author}}</td>
                    <td><button (click)="deleteCourse(course.course_id)" class='btn btn-primary'><i class="fa fa-futboll-0">Delete</i></button>   
                      <button (click)="updateCourse(course.course_id)" class='btn btn-info'  
                      data-toggle="modal" data-target="#myModal" >Update</button>  
                    </td>  
                  </tr>   
            </tbody><br>  
        </table>  
    </div>  
  </div>     
    
   
   <div class="modal" id="myModal">  
          <div class="modal-dialog">  
            <div class="modal-content">  
                  <form [formGroup]="courseupdateform" #updcur (ngSubmit)="updateCur(updcur)">  
                
              <div class="modal-header">  
                <h4 class="modal-title" style="text-align: center">Update Course</h4>  
                                        
              </div>  
                
                    
              <div class="modal-body" >  
                  <div [hidden]="isupdated">  
                      
    
                      <input type="hidden" class="form-control"  formControlName="course_id" [(ngModel)]="crid">  
                              
                                                <div class="form-group">  
                                  <label for="name">Course Name</label> 
                                  <input type="text" class="form-control"  formControlName="course_name" [(ngModel)]="cname"  >  
                              </div>  
                        
                              <div class="form-group">  
                                  <label for="name">Course Duration</label>  
                                  <input type="text" class="form-control" formControlName="course_duration" [(ngModel)]="cduration">  
                              </div>  
                              <div class="form-group">  
                                    <label for="name">Course Fee</label>  
                                    <input type="text" class="form-control" formControlName="course_fee" [(ngModel)]="cfee">  
                                </div>  
                                <div class="form-group">  
                                        <label for="name">Course Author</label>  
                                        <input type="text" class="form-control" formControlName="course_author" [(ngModel)]="cauthor">  
                                    </div>  
                                                  
                    </div>    
                    <div [hidden]="!isupdated">  
                        <h4>Course Detail Updated!</h4>  
                    </div>              
                        
              </div>  
                
                
              <div class="modal-footer" >  
                <button type="submit" class="btn btn-success" [hidden]="isupdated">Update</button>  
                <button type="button" class="btn btn-danger" data-dismiss="modal" (click)="changeisUpdate()">Close</button>  
              </div>  
                
          </form>  
            </div>  
          </div>  
        </div>   

Step 12: Update add-course.component.ts file as below

import { Component, OnInit } from '@angular/core';
import { CourseService } from '../course.service';  
import {FormControl,FormGroup,Validators} from '@angular/forms';  
import { Course } from '../course';  
import { Observable,Subject } from "rxjs";

@Component({
  selector: 'app-add-course',
  templateUrl: './add-course.component.html',
  styleUrls: ['./add-course.component.css']
})
export class AddCourseComponent implements OnInit {   

  constructor(private courseService:CourseService) { }  
  
  courses: Observable<Course[]>;

  course : Course=new Course();  
  submitted = false;  
  
  ngOnInit() {  
    this.submitted=false;  
    this.courseService.getCourseList().subscribe(data =>{
      this.courses =data; 
      console.log(this.courses);

      })
  }  
  
  coursesaveform=new FormGroup({  
    //course_id:new FormControl(),
    course_name:new FormControl('' , [Validators.required , Validators.minLength(5) ] ),  
    course_fee:new FormControl(),  
    course_duration:new FormControl(),
    course_author:new FormControl()  
  });  
  
  saveCourse(saveCourse){  
    this.course=new Course(); 
    //this.course.course_id = this.CourseId.value;
    this.course.course_name=this.CourseName.value;  
    this.course.course_fee = Number(this.CourseFee.value);  
    this.course.course_duration=Number(this.CourseDuration.value);  
    this.course.course_author = this.CourseAuthor.value;
    this.submitted = true;  
    this.save();  
  }     
  save() {  
    this.courseService.createCourse(this.course)  
      .subscribe(data => console.log(data), error => console.log(error));  
      console.log(this.course);
    this.course = new Course();  
  }  
 
  get CourseName(){  
    return this.coursesaveform.get('course_name');  
  }  

  get CourseId(){  
    return this.coursesaveform.get('course_id');  
  }
  
  get CourseDuration(){  
    return this.coursesaveform.get('course_duration');  
  }  
  
  get CourseFee(){  
    return this.coursesaveform.get('course_fee');  
  }  

  get CourseAuthor(){  
    return this.coursesaveform.get('course_author');  
  }
  
  addCourseForm(){  
    this.submitted=false;  
    this.coursesaveform.reset();  
  }  

}

Step 13: Update add-course.component.html as below

<h3>Create Course</h3>  
<div class="row">   
  <div class="col-sm-4"></div>  
  <div class="col-sm-4" >  
    <div [hidden]="submitted" style="width: 400px;">  
      <form [formGroup]="coursesaveform" #savecourse (ngSubmit)="saveCourse(saveCourse)">  
         
            <div class="form-group">  
              <label for="name">Course Name</label>  
              <input type="text" class="form-control"  formControlName="course_name" data-toggle="tooltip"   
                 data-placement="right" title="Enter Course Name" >  
              <div class="alert alert-danger" *ngIf = "(CourseName.touched) && (CourseName.invalid)"   
                style="margin-top: 5px;">  
                  <span *ngIf="CourseName.errors.required">Course Name is Required</span>  
                    <span *ngIf = "CourseName.errors.minlength">   
                        MinLength Error   
                    </span>                     
                </div>  
          </div>  
    
          <div class="form-group">  
              <label for="name">Course Author</label>  
              <input type="text" class="form-control" formControlName="course_author"   
                data-toggle="tooltip" data-placement="right" title="Enter Course Author">  
                <div class="alert alert-danger" *ngIf = "(CourseAuthor.touched) && (CourseAuthor.invalid)"   
                style="margin-top: 5px;">  
                  <span *ngIf="CourseAuthor.errors.required">Course Author is Required</span>  
                                       
                </div>  
          </div>  

          <div class="form-group">  
            <label for="name">Course Fee</label>  
            <input type="text" class="form-control" formControlName="course_fee"   
              data-toggle="tooltip" data-placement="right" title="Enter Course Fee">  
              <div class="alert alert-danger" *ngIf = "(CourseFee.touched) && (CourseFee.invalid)"   
              style="margin-top: 5px;">  
                <span *ngIf="CourseFee.errors.required">Course Fee is Required</span>  
                                     
              </div>  
        </div>  

        <div class="form-group">  
            <label for="name">Course Duration</label>  
            <input type="text" class="form-control" formControlName="course_duration"   
              data-toggle="tooltip" data-placement="right" title="Enter Course Fee">  
              <div class="alert alert-danger" *ngIf = "(CourseDuration.touched) && (CourseDuration.invalid)"   
              style="margin-top: 5px;">  
                <span *ngIf="CourseDuration.errors.required">Course Duration is Required</span>  
                                     
              </div>  
        </div>   
        
    
          <button type="submit" class="btn btn-success">Submit</button>  
      </form>  
  </div>  
  </div>  
  <div class="col-sm-4"></div>  
</div>  
<div class="row">  
  <div class="col-sm-4"></div>  
  <div class="col-sm-4">  
      <div [hidden]="!submitted">  
         <h4>Course Added SuccessFully!</h4>  
         <button (click)="addCourseForm()" class='btn btn-primary'>Add More Course</button>  
      </div>        
  </div>  
  <div class="col-sm-4"></div>  
</div>  

Step 14: Update app.component.html as below

<div  class="container-fluid">  
  <nav class="navbar navbar-expand-sm bg-dark navbar-dark">  
      <ul class="navbar-nav">  
        <li class="nav-item ">  
          <a routerLink="view-course" class="nav-link" class="btn btn-primary active" role="button" >View Course</a>       
        </li>   
        <li class="nav-item">  
          <a  routerLink="add-course" class="nav-link" class="btn btn-primary active" role="button" >Add Course</a>  
        </li>            
      </ul>  
    </nav>     
      <router-outlet></router-outlet>  
  </div>  

Step 15: Run the application

C:\Users\Girish\AngularProjects\my-rest-app>ng serve

Step 16: Service URL

Created the Rest Service in Sprint Boot. Application is running on Tomcat 9 Server at port 8080. This Rest Service example you can see in our Spring Framework Tutorials.

http://localhost:8080/demo/

You can use PostMan tool or any other REST clients to test the REST URL

MySQL Table Script

Use db_example;
CREATE TABLE `course` (
  `course_id` int(11) NOT NULL,
  `course_author` varchar(255) DEFAULT NULL,
  `course_duration` int(11) NOT NULL,
  `course_fee` int(11) NOT NULL,
  `course_name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`course_id`)
) ;

Service Methods

  • GetAllCourses
  • GetCourseById
  • DeleteCourseById
  • SaveCourse
  • UpdateCourseById
Request GET - http://localhost:8080/demo/allcourses
Response (JSON)
[
    {
        "course_id": 1,
        "course_name": "Python",
        "course_author": "Girish",
        "course_fee": 450,
        "course_duration": 30
    },
    {
        "course_id": 2,
        "course_name": "Full Stack Java",
        "course_author": "Sanjay",
        "course_fee": 550,
        "course_duration": 40
    }
  
]

Request GET: http://localhost:8080/demo/getcoursebyid/25
Response (JSON)
{
    "course_id": 25,
    "course_name": "Solidity",
    "course_author": "Srinivas Galma",
    "course_fee": 250,
    "course_duration": 35
}

Request DELETE : http://localhost:8080/demo/deleteCourse/25
Response
"OK"

Request POST: http://localhost:8080/demo/saveCourse
{ 
    "course_name": "Express.js",
    "course_author": "Girishr",
    "course_fee": 350,
    "course_duration": 30 
     
}
Response (JSON)
{
    "course_id": 31,
    "course_name": "Express.js",
    "course_author": "Girishr",
    "course_fee": 350,
    "course_duration": 30
}

Request POST: http://localhost:8080/demo/update/31
{
    "course_id": 31,
    "course_name": "Express.js",
    "course_author": "Krishna",
    "course_fee": 350,
    "course_duration": 30
}
Response (JSON)
{
    "course_id": 31,
    "course_name": "Express.js",
    "course_author": "Krishna",
    "course_fee": 350,
    "course_duration": 30
}

To understand this example you need to understand the concepts of Observables, Reactive Forms, Service, Dependency Injection. Reactive Forms and Observables concepts I will explain in detail in our upcoming Angular articles.

References

  • https://angular.io/guide/http
  • https://angular.io/guide/observables
  • https://angular.io/guide/reactive-forms

Learn more about Angular features in our upcoming Angular articles.

Happy Learning!