Angular web application framework is used by developers to create reactive Single-Page-Applications (SPAs). To give you a background on Single-Page Applications, they’re web applications that load a single HTML page and dynamically update the page in response to user’s interaction.

Developers build Angular applications using TypeScript and Angular Command Line Interface (CLI), TypeScript is a popular open source programming language that is developed and maintained by Microsoft. Whereas, Angular CLI is a tool that is used to create projects, add files, and perform a variety of ongoing development tasks such as bundling, deployment, and testing. In this post, we will figure out the process to integrate Angular with Spring Boot RESTful API.

Building Blocks of Angular 

Here are the primary building blocks of Angular web application framework.

  • Modules
  • Components
  • Templates
  • Metadata
  • Data binding
  • Directives
  • Services
  • Dependency injection

Angular Building Blocks

Building Application Using Angular and Spring Boot

To begin, let us build a simple employee management system and include add, get and delete operations. For generating Angular components, we can use Angular CLI. The Angular components talk to the back-end via REST to perform various tasks.

Here is the technology stack used for our employee management application.

  • Java 1.8 + Spring Boot (Back-end)
  • Angular 4 + Node.js (Front-end)
  • Spring Tool Suite (IDE)
1. Install Node.js for Angular

Download and install Node.js from their website. If the installation is successful, you would see the following items on entering the command, node –v & npm -v:

Install Node.js for Angular

2. Install Angular-CLI

Next, install Angular by using the command, npm install -g @angular/cli

Install Angular-CLI

3. Create Angular Client Project

On the command line, navigate to your IDE’s workspace by entering, CD C:\Users\User\workspace (specify your workspace path here). Start a new Angular project by entering ng new angular4-client –routing.

4. Import Angular Client Project
  • Import Angular client project into Spring Tool Suite.
  • Open the Spring Tool Suite (STS), go to Import -> General -> Projects from Folder or Archive, press the ‘Next’ option.
  • Upon successful import, you would be able to view the following project structure in your IDE.

Import Angular 4 Client Project

To clean the source code in STS remove node_modules by following these steps:

  • Right-click on the angular4-client project, choose Properties, then select Resource -> Resource Filter.
  • Press Add Filter…, choose Filter Type: Exclude all, Applies to: files and folders, and check all children (recursive), with file and folder attributes, specify node_modules. This should remove node_modules from showing up in STS.

Now, start the angular4-client project with STS:

  • Go to Window -> Show View -> Other (search and choose terminal).
  • Then launch a local terminal, CD to C:\Users\User\workspace\angular4-client
5. Generate Components

Use below command to generate the employee module.

ng generate module employee –routing

We need a service to call the REST services. Use below command to generate an employee service.

ng generate service employee/employee

Now we have to generate sub-components.

ng generate component /employee/employee-list

Generate Components

1. Routing

Now modify employee-routing.module.ts in the employee module.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EmployeeListComponent } from './employee-list/employee-list.component';
const routes: Routes = [
{path: 'api/employees', component: EmployeeListComponent},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class EmployeeRoutingModule { }

Then, add the EmployeeModule in the app.module.ts.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { AppRoutingModule } from './app-routing.module';
import {FormsModule,ReactiveFormsModule} from '@angular/forms';
import { AppComponent } from './app.component';
import { EmployeeModule } from './employee/employee.module';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
AppRoutingModule,
HttpModule,
EmployeeModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
2. Styling

Go to the angular4-client and run following command.

npm install --save bootstrap font-awesome

Then open styles.css and import

@import "~bootstrap/dist/css/bootstrap.min.css";
@import "~font-awesome/css/font-awesome.css";
3. Showing Employee Details

Open employee.ts inside the employee module.

export class Employee{
id: number;
firstName: string;
phoneNo: number;
email: string;
constructor(id: number, firstName: string, phoneNo: number, email: string){
this.id = id;
this.firstName = firstName;
this.phoneNo = phoneNo;
this.email = email;
}
}
  • employee.service.ts is responsible to call the server side REST API.
import { Injectable } from '@angular/core';
import { Employee } from "./employee";
import { Http, Response } from "@angular/http";
import { Headers, RequestOptions } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable()
export class EmployeeService {
private apiUrl = '/api/employees';
constructor(private http: Http) {
 }
findAll(): Promise<Array<Employee>> {
 return this.http.get(this.apiUrl)
 .toPromise()
 .then(response => response.json() as Employee[])
 .catch(this.handleError);
 }
createEmployee(employee: Employee): Promise<Array<Employee>> {
 let empHeaders = new Headers({ 'Content-Type': 'application/json' });
 return this.http.post(this.apiUrl, JSON.stringify(employee), { headers: empHeaders })
 .toPromise()
 .then(response => response.json() as Employee[])
 .catch(this.handleError);
 }
deleteEmployeeById(id: number): Promise<Array<Employee>> {
 const url = `${this.apiUrl}/${id}`;
 return this.http.delete(url)
 .toPromise()
 .then(response => response.json() as Employee[])
 .catch(this.handleError);
 }
private handleError(error: any): Promise<Array<any>> {
 console.error('An error occurred', error);
 return Promise.reject(error.message || error);
 }
}
  • employee-list.component.ts is responsible to call service and get all employees details
import { Component, OnInit, Input } from '@angular/core';
import { Employee } from "../employee";
import { EmployeeService } from "../employee.service";
import { Router } from '@angular/router';
@Component({
 selector: 'app-employee-list',
 templateUrl: './employee-list.component.html',
 styleUrls: ['./employee-list.component.css'],
 providers: [EmployeeService]
})
export class EmployeeListComponent implements OnInit {
private employees: Employee[];
constructor(private router: Router,
 private employeeService: EmployeeService) { }
ngOnInit() {
 this.getAllEmployees();
 }
getAllEmployees() {
 this.employeeService.findAll().then(
 employees => {
 this.employees = employees;
 },
 err => {
 console.log(err);
 }
);
 }
createEmployee() {
 let firstName = (<HTMLInputElement>document.getElementById('firstName')).value;
 let phoneNo = (<HTMLInputElement>document.getElementById('phoneNo')).value;
 let email = (<HTMLInputElement>document.getElementById('email')).value;
 let employee = new Employee(0, firstName, Number(phoneNo), email);
 this.employeeService.createEmployee(employee).then(
 employees => {
 this.employees = employees;
 },
 err => {
 console.log(err);
 }
 );
 }
deleteEmployee(employee: Employee) {
 this.employeeService.deleteEmployeeById(employee.id).then(
 employees => {
 this.employees = employees;
 },
 err => {
 console.log(err);
 }
 );
 }
}
  • Now build a simple HTML file, employee-list.component.html, with add/delete events.
<div class="container">
 <div class="row">
 <div class="col">
 <section>
 <header class="header">
 <div class="row">
 <div class="col-md-2">
 <form name="empForm"> 
 <table>
  <tr>
 <th colspan="2">Add Employee</th>
 </tr>
 <tr>
 <td>FirstName:</td>
 <td><input id="firstName" name="firstName" ></td>
 </tr>
 <tr>
 <td>Phone No:</td>
 <td><input id="phoneNo" name="phoneNo"></td>
 </tr>
 <tr>
 <td>Email:</td>
 <td><input id="email" name="email"></td>
 </tr>
 <tr>
 <td colspan="2"> <button type="button" (click)="createEmployee()" class="blue-button">submit</button></td>
 </tr>
 </table>
 </form>
 </div>
 </div>
</header>
 </section>
<section class="main">
<table class="table">
 <thead>
 <tr>
 <th>#</th>
 <th>First Name</th>
 <th>Phone No</th>
 <th>Email</th>
 <th></th>
 </tr>
 </thead>
 <tbody>
 <tr *ngFor="let employee of employees">
 <th scope="row">{{employee.id}}</th>
 <td>{{employee.firstName}}</td>
 <td>{{employee.phoneNo}}</td>
 <td>{{employee.email}}</td>
 <td>
 <button type="button" class="btn btn-danger" (click)="deleteEmployee(employee)">Delete</button>
 </td>
 </tr>
</tbody>
 </table>
 </section>
 </div>
 </div>
</div>
4. Create Spring Boot Application
  • Create EmployeeController.java and add the below code
package com.springangular4.restful.controller;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.springangular4.model.Employee;
@RestController
@RequestMapping(value = "/api/employees")
public class EmployeeController {
private List<Employee> employees = new ArrayList<Employee>();
EmployeeController() {
this.employees = buildEmployees();
}
@RequestMapping(method = RequestMethod.GET)
public List<Employee> getEmployees() {
return this.employees;
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public Employee getEmployee(@PathVariable("id") Long id) {
return this.employees.stream().filter(emp -> emp.getId() == id).findFirst().orElse(null);
}
@RequestMapping(method = RequestMethod.POST)
public List<Employee> saveEmployee(@RequestBody Employee emp) {
Long nextId = 0L;
if (this.employees.size() != 0) {
Employee lastEmp = this.employees.stream().skip(this.employees.size() - 1).findFirst().orElse(null);
nextId = lastEmp.getId() + 1;
}
emp.setId(nextId);
this.employees.add(emp);
return this.employees;
}
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public List<Employee> deleteEmployee(@PathVariable Long id) {
for(Iterator<Employee> itr=this.employees.iterator();itr.hasNext();)
{
Employee emp = itr.next();
Long inId = emp.getId();
if(inId == (id)){
itr.remove();
}
}
return this.employees;
}
List<Employee> buildEmployees() {
List<Employee> emps = new ArrayList<>();
Employee emp1 = buildEmployee(1L, "venu", 9553226588L, "venu@email.com");
Employee emp2 = buildEmployee(2L, "krishna", 8654782255L, "krish@email.com");
emps.add(emp1);
emps.add(emp2);
return emps;
}
Employee buildEmployee(Long id, String fname, Long phoneNo, String email) {
Employee emp = new Employee(id, fname, phoneNo, email);
return emp;
}
}
  • Create Employee.java with getters/setters.
package com.springangular4.model;
import java.io.Serializable;
public class Employee implements Serializable {
private static final long serialVersionUID = -8809089768201955649L;
private Long id;
private String firstName;
private Long phoneNo;
private String email;
public Employee(){}
public Employee(Long id, String firstName, Long phoneNo, String email) {
super();
this.id = id;
this.firstName = firstName;
this.phoneNo = phoneNo;
this.email = email;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Long getPhoneNo() {
return phoneNo;
}
public void setPhoneNo(Long phoneNo) {
this.phoneNo = phoneNo;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
5. Integrate Angular and Spring Boot

Up to now, Angular4-Client and Spring Boot server worked independently on ports 8080 and 4200. The goal of the below integration is to ensure that client at 4200 will proxy any API requests to the server.

Steps to Follow
  • Create a file proxy.conf.json under project angular4-client folder with content:
{
"/api":{
"target": "http://localhost:8080",
"secure": false
}
}
  • Edit package.json file for start script:
"start": "ng serve --proxy-config proxy.conf.json",
  • Build and run Spring Boot application with below commands
mvn clean install
mvn spring-boot:run
  • Build and Run Angular4-client with below commands
 ng build
npm start 

Type the URL http://localhost:4200 into your browser and you are all set. Here is the snapshot of the output screen.

Angular App

Choose Evoke Technologies for Consistent Deliverables

We at Evoke Technologies bring more than a decade’s experience as an IT leader in designing and implementing open source solutions for global enterprises. Our dedicated open source experts will understand your company’s most pressing challenges and guide you in developing an open source solutions plan to meet them. Whether its customer relationship management, content management, quality assurance or more, Evoke has open source expertise to benefit your business.

Contact Evoke Technologies at (937) 660-4923, and learn how we, as your open source solution provider, can start making your company’s software development and operations budget go farther today!