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
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:
2. Install Angular-CLI
Next, install Angular by using the command, npm install -g @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.
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.
[java]
ng generate module employee –routing
[/java]
We need a service to call the REST services. Use below command to generate an employee service.
[java]
ng generate service employee/employee
[/java]
Now we have to generate sub-components.
[java]
ng generate component /employee/employee-list
[/java]
1. Routing
Now modify employee-routing.module.ts in the employee module.
[java]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 { }[/java]
Then, add the EmployeeModule in the app.module.ts.
[java]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 { }[/java]
2. Styling
Go to the angular4-client and run following command.
[java]
npm install –save bootstrap font-awesome
[/java]
Then open styles.css and import
[html]
@import “~bootstrap/dist/css/bootstrap.min.css”;
@import “~font-awesome/css/font-awesome.css”;
[/html]
3. Showing Employee Details
Open employee.ts inside the employee module.
[java]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;
}
}[/java]
- employee.service.ts is responsible to call the server side REST API.
[java]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);
}
}[/java]
- employee-list.component.ts is responsible to call service and get all employees details
[php]
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);
}
);
}
}
[/php]
- Now build a simple HTML file, employee-list.component.html, with add/delete events.
[html]<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>
[/html]
4. Create Spring Boot Application
- Create EmployeeController.java and add the below code
[java]
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;
}
}
[/java]
- Create Employee.java with getters/setters.
[java]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;
}
}[/java]
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:
[java]
{
“/api”:{
“target”: “http://localhost:8080”,
“secure”: false
}
}
[/java]
- Edit package.json file for start script:
[java]
“start”: “ng serve –proxy-config proxy.conf.json”,
[/java]
- Build and run Spring Boot application with below commands
[java]
mvn clean install
mvn spring-boot:run
[/java]
- Build and Run Angular4-client with below commands
[java] ng build
npm start
[/java]
Type the URL http://localhost:4200 into your browser and you are all set. Here is the snapshot of the output screen.
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!
Author
Venugopal Bathina is a Senior Technical Associate at Evoke Technologies. Venu has extensive experience on various leading-edge technologies, including JAVA/J2EE, Oracle ATG, and Pega. He is extremely passionate about emerging tech trends and likes writing data-driven content. |
35 Comments
nice blog!
Very helpful for a beginner like me. thanks a lot
Please provide to download source code.
please follow above steps, you are able to create project.
Hey… Nice one. But I still don’t get it. Where and how did you include employee-list component html in your main html? As we know that app.component is executed first, then how can we execute employee-list through app.component?
The EmployeeController.java and Employee.java in where folder should be placed?
Create folders based on package name.
Where should the java files/folders should be placed/created? Can you show the folder structure/tree?
It will be really very helpful for beginners if you share the tree structure of whole project as well. Thank you.
What is the content of employee.module.ts?
Angular will generate employee.module.ts by default.
no it didnt create by default
I tried to run the same project and got Module not found: Error: Can’t resolve ‘rxjs/add/operator/toPromise’.
Do you have any suggestion how to fix this issue? Thanks
you missed to import some of the modules like below.
import ‘rxjs/add/operator/toPromise’;
import { HttpClient, HttpHeaders } from ‘@angular/common/http’;
I am able to setup both app-server and app-client locally, when when i tried to pull both in single war file, it’s not working.
Can you please share the pom.xml file as well for app-server?
In the article “How to Integrate Angular with Spring Boot RESTful API” why you are removing node_modules from the angular project after importing it into eclipse. I am thinking that this is having the supporting libraries for the angular project if we remove it then how the project will run.
It’s not removed but hidden in eclipse.
Nice work!. Do you have updated code for Angular 6+?
I don’t have updated code for Angular 6+.
i’m trying to add the employee details in angular and its not getting added ….
getting errors like :
Failed to load http://localhost:8080/api/employee: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:4200’ is therefore not allowed access.
Hi,
I have java server (backend) running in 8080 // All the API are here
and Angular running in 4200
While i’m trying to connect one of the login API in java from Angular im getting cross domain error
Access to XMLHttpRequest at ‘http://localhost:8080/AppvanceServer/rest/admin/loggin’ from origin ‘http://localhost:4200’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
What is the best/stable way to connect angular and java ?
Thanks,
M Subash Chandrabose
Sir Can You upload entire Project on GitHub or some other Platform..It will be very useful for begineers..
Thanks
Sir can you provide source code for this project..
Hey… Nice one. But I still don’t get it. Where and how did you include employee-list component html in your main html? As we know that app.component is executed first, then how can we execute employee-list through app.component?
mine also same problem please help
Hi, we need to change the entry component of the project . to get the detailed explanation follow the link
https://stackoverflow.com/questions/47225812/index-html-integration-with-app-component-html-template-in-angular-2
But to answer your question. We need to change
bootstrap[AppComponent] ————> bootstrap: [EmployeeListComponent]
in app.module.ts.
The getAllEmployees() was called in ngOInit() so if you know lifecycle hooks u will understand it.
can you please entire source code for this project .. its helpful for beginners
No puedo importar el HttpModule me dice que no encuentra en @angular/http lo necesito para un proyecto urgente
tengo otra duda el controller y la clase java en que carpeta se va a crear
Hi Sir,
It is really nice and helpful. I was looking for exactly this. I want to know how can we package both the angular and spring boot service app together for installing in production.
Nice Explanation Sir
It is really helpful for me like new angular users
There is no employee.ts file?
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;
}
}
An unhandled exception occurred: Class extends value undefined is not a constructor or null ,
[error] TypeError: Class extends value undefined is not a constructor or null
at Object. (C:\Users\Ritzz\node_modules\mini-css-extract-plugin\dist\CssDependency.js:12:46)
at Module._compile (internal/modules/cjs/loader.js:1151:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1171:10)
at Module.load (internal/modules/cjs/loader.js:1000:32)
at Function.Module._load (internal/modules/cjs/loader.js:899:14)
at Module.require (internal/modules/cjs/loader.js:1040:19)
at require (internal/modules/cjs/helpers.js:72:18)
at Object. (C:\Users\Ritzz\node_modules\mini-css-extract-plugin\dist\index.js:12:45)
at Module._compile (internal/modules/cjs/loader.js:1151:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1171:10)
at Module.load (internal/modules/cjs/loader.js:1000:32)
at Function.Module._load (internal/modules/cjs/loader.js:899:14)
at Module.require (internal/modules/cjs/loader.js:1040:19)
at require (internal/modules/cjs/helpers.js:72:18)
at Object. (C:\Users\Ritzz\node_modules\mini-css-extract-plugin\dist\cjs.js:3:18)
at Module._compile (internal/modules/cjs/loader.js:1151:30)
please help me with this