📘 Premium Read: Access my best content on Medium member-only articles — deep dives into Java, Spring Boot, Microservices, backend architecture, interview preparation, career advice, and industry-standard best practices.
🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.
▶️ Subscribe to My YouTube Channel (176K+ subscribers): Java Guides on YouTube
▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube
If you are looking for Angular 6 with spring boot 2 integration example then check out Spring Boot + Angular 6 CRUD Example article.
You can download the source code of this tutorial from my GitHub repository at the end of this tutorial.
Recommendation - Check out the same tutorial upgraded using the latest release of Angular 8 at Spring Boot + Angular 8 CRUD Example Tutorial // Recommended the latest release of Angular 8.
Spring Boot + Angular 8 CRUD Example Tutorial
Video Tutorial
What you'll learn
- You will develop your first FULL STACK Application with Angular 7 and Spring Boot
- You will learn the basics of building AWESOME Frontend Applications with Angular 7
- You will be introduced to building great RESTful APIs with Spring Boot
- You will learn to solve the challenges of connecting an Angular frontend to a RESTful API
- You will learn the basics of Angular - Angular Modules, Components, Data Binding and Routing
- You will learn to connect REST API to JPA/Hibernate with Spring Boot
- You will learn to use a wide variety of Spring Boot Starter Projects - Spring Boot Web, and Spring Boot Data JPA
What we will build?
- springboot2-jpa-crud-example: This project is used to develop CRUD RESTFul APIs for a simple Employee Management System using Spring Boot 2, JPA and MySQL as a database.
- angular7-springboot-client: This project is used to develop single page application using Angular 7 as front-end technology. This Angular 7 application consumes CRUD Restful APIs developed and exposed by a springboot2-jpa-crud-example project.
Tools and technologies used
Server-side technologies
- Spring Boot - 2.0.4.RELEASE
- JDK - 1.8 or later
- Spring Framework - 5.0.8 RELEASE
- Hibernate - 5.2.17.Final
- Spring Data JPA - 2+
Front end technologies
- Angular 7.2
- Bootstrap 4
- npm- 6.4.1
- JQuery
Tools
- Maven - 3.2+
- IDE - Eclipse or Spring Tool Suite (STS)
- Visual Studio 2017
- Angular CLI
Features Implementation
- Create an Employee
- Update an Employee
- List of Employees
- Delete Employee
- View Employee
- You will develop your first FULL STACK Application with Angular 8 and Spring Boot.
Important: Note that update employee and view employee features covered in
Spring Boot + Angular 8 CRUD Example Tutorial.
Spring Boot CRUD Rest APIs
1. Creating and Importing a Project
- Generate: Maven Project
- Java Version: 1.8 (Default)
- Spring Boot:2.0.4
- Group: net.guides.springboot2
- Artifact: springboot2-jpa-crud-example
- Name: springboot2-jpa-crud-example
- Description: Rest API for a Simple Employee Management Application
- Package Name : net.guides.springboot2.springboot2jpacrudexample
- Packaging: jar (This is the default value)
- Dependencies: Web, JPA, MySQL, DevTools
2. Packaging Structure
3. The pom.xml File
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.guides.springboot2</groupId>
<artifactId>springboot2-jpa-crud-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot2-jpa-crud-example</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4. Configuring MySQL Database
spring.datasource.url = jdbc:mysql://localhost:3306/users_database?useSSL=false
spring.datasource.username = root
spring.datasource.password = root
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
5. Create JPA Entity - Employee.java
package net.guides.springboot2.springboot2jpacrudexample.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "employees")
public class Employee {
private long id;
private String firstName;
private String lastName;
private String emailId;
public Employee() {
}
public Employee(String firstName, String lastName, String emailId) {
this.firstName = firstName;
this.lastName = lastName;
this.emailId = emailId;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Column(name = "first_name", nullable = false)
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@Column(name = "last_name", nullable = false)
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Column(name = "email_address", nullable = false)
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
@Override
public String toString() {
return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", emailId=" + emailId
+ "]";
}
}
6. Create a Spring Data Repository - EmployeeRepository.java
package net.guides.springboot2.springboot2jpacrudexample.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import net.guides.springboot2.springboot2jpacrudexample.model.Employee;
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long>{
}
7. Create Spring Rest Controller - EmployeeController.java
package net.guides.springboot2.springboot2jpacrudexample.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import net.guides.springboot2.springboot2jpacrudexample.exception.ResourceNotFoundException;
import net.guides.springboot2.springboot2jpacrudexample.model.Employee;
import net.guides.springboot2.springboot2jpacrudexample.repository.EmployeeRepository;
@RestController
@RequestMapping("/api/v1")
public class EmployeeController {
@Autowired
private EmployeeRepository employeeRepository;
@GetMapping("/employees")
public List<Employee> getAllEmployees() {
return employeeRepository.findAll();
}
@GetMapping("/employees/{id}")
public ResponseEntity<Employee> getEmployeeById(@PathVariable(value = "id") Long employeeId)
throws ResourceNotFoundException {
Employee employee = employeeRepository.findById(employeeId)
.orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));
return ResponseEntity.ok().body(employee);
}
@PostMapping("/employees")
public Employee createEmployee(@Valid @RequestBody Employee employee) {
return employeeRepository.save(employee);
}
@PutMapping("/employees/{id}")
public ResponseEntity<Employee> updateEmployee(@PathVariable(value = "id") Long employeeId,
@Valid @RequestBody Employee employeeDetails) throws ResourceNotFoundException {
Employee employee = employeeRepository.findById(employeeId)
.orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));
employee.setEmailId(employeeDetails.getEmailId());
employee.setLastName(employeeDetails.getLastName());
employee.setFirstName(employeeDetails.getFirstName());
final Employee updatedEmployee = employeeRepository.save(employee);
return ResponseEntity.ok(updatedEmployee);
}
@DeleteMapping("/employees/{id}")
public Map<String, Boolean> deleteEmployee(@PathVariable(value = "id") Long employeeId)
throws ResourceNotFoundException {
Employee employee = employeeRepository.findById(employeeId)
.orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));
employeeRepository.delete(employee);
Map<String, Boolean> response = new HashMap<>();
response.put("deleted", Boolean.TRUE);
return response;
}
}
8. Exception(Error) Handling for RESTful Services
Resource Not Present
Heres what happens when you fire a request to not resource found: http://localhost:8080/some-dummy-url{
"timestamp": 1512713804164,
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/some-dummy-url"
}
What happens when we throw an Exception?
package com.companyname.springbootcrudrest.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends Exception{
private static final long serialVersionUID = 1L;
public ResourceNotFoundException(String message){
super(message);
}
}
Customizing Error Response Structure
package com.companyname.springbootcrudrest.exception;
import java.util.Date;
public class ErrorDetails {
private Date timestamp;
private String message;
private String details;
public ErrorDetails(Date timestamp, String message, String details) {
super();
this.timestamp = timestamp;
this.message = message;
this.details = details;
}
public Date getTimestamp() {
return timestamp;
}
public String getMessage() {
return message;
}
public String getDetails() {
return details;
}
}
package com.companyname.springbootcrudrest.exception;
import java.util.Date;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<?> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<?> globleExcpetionHandler(Exception ex, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
9. Running Application
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
This completes the development of Spring boot CRUD Rest APIs. Now we will develop client application using Angular 7.
Angular 7 Client Application Development
Good to know Angular 7 release notes and new features at Version 7 of Angular — CLI Prompts, Virtual Scroll, Drag and Drop and more.
node -v
v8.12.0
npm -v
6.4.1
That's the Node.js and NPM version that we are using. Now, you can go to the main steps.Install or Update Angular 7 CLI and Create Application
To install or update Angular 7 CLI, type this command in the Terminal or Node Command-Line.npm install -g @angular/cli
Now, you have the latest version of Angular CLI.ng --version
Angular CLI: 7.0.1
Node: 8.12.0
OS: darwin x64
Angular:
...
Package Version
------------------------------------------------------
@angular-devkit/architect 0.10.1
@angular-devkit/core 7.0.1
@angular-devkit/schematics 7.0.1
@schematics/angular 7.0.1
@schematics/update 0.10.1
rxjs 6.3.3
typescript 3.1.3
Next, create a new Angular 7 Web Application using this Angular CLI command.Create Angular 7 client application using Angular CLI
ng new angular7-springboot-client
Components, Services, and Modules
- Components
- create-employee
- employee-list
- employee-details
- Services
- employee.service.ts - Service for Http Client methods
- Modules
- FormsModule
- HttpClientModule
- AppRoutingModule.
- Employee Class (Typescript class)
- employee.ts: class Employee (id, firstName, lastName, emailId)
Create Service & Components
- ng g s employee
– ng g c create-employee
– ng g c employee-details
– ng g c employee-list
C:\angular7\angular7-springboot-client\src\app>ng g s employee
CREATE src/app/employee.service.spec.ts (343 bytes)
CREATE src/app/employee.service.ts (137 bytes)
C:\angular7\angular7-springboot-client\src\app>ng g c create-employee
CREATE src/app/create-employee/create-employee.component.html (34 bytes)
CREATE src/app/create-employee/create-employee.component.spec.ts (685 bytes)
CREATE src/app/create-employee/create-employee.component.ts (304 bytes)
CREATE src/app/create-employee/create-employee.component.css (0 bytes)
UPDATE src/app/app.module.ts (509 bytes)
C:\angular7\angular7-springboot-client\src\app>ng g c employee-details
CREATE src/app/employee-details/employee-details.component.html (35 bytes)
CREATE src/app/employee-details/employee-details.component.spec.ts (692 bytes)
CREATE src/app/employee-details/employee-details.component.ts (308 bytes)
CREATE src/app/employee-details/employee-details.component.css (0 bytes)
UPDATE src/app/app.module.ts (629 bytes)
C:\angular7\angular7-springboot-client\src\app>ng g c employee-list
CREATE src/app/employee-list/employee-list.component.html (32 bytes)
CREATE src/app/employee-list/employee-list.component.spec.ts (671 bytes)
CREATE src/app/employee-list/employee-list.component.ts (296 bytes)
CREATE src/app/employee-list/employee-list.component.css (0 bytes)
UPDATE src/app/app.module.ts (737 bytes)
Integrate Bootstrap with Angular
npm install bootstrap jquery --save
...
"styles": [
"src/styles.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/bootstrap/dist/js/bootstrap.min.js"
]
...
package.json
This file Configures npm package dependencies that are available to all projects in the workspace.Note that angular version 7.2.0 in dependencies section in below file.
{ "name": "angular7-springboot-client", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve --proxy-config proxy.conf.json", "build": "ng build", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" }, "private": true, "dependencies": { "@angular/animations": "~7.2.0", "@angular/common": "~7.2.0", "@angular/compiler": "~7.2.0", "@angular/core": "~7.2.0", "@angular/forms": "~7.2.0", "@angular/platform-browser": "~7.2.0", "@angular/platform-browser-dynamic": "~7.2.0", "@angular/router": "~7.2.0", "bootstrap": "^4.2.1", "core-js": "^2.5.4", "jquery": "^3.3.1", "rxjs": "~6.3.3", "tslib": "^1.9.0", "zone.js": "~0.8.26" }, "devDependencies": { "@angular-devkit/build-angular": "~0.12.0", "@angular/cli": "~7.2.1", "@angular/compiler-cli": "~7.2.0", "@angular/language-service": "~7.2.0", "@types/node": "~8.9.4", "@types/jasmine": "~2.8.8", "@types/jasminewd2": "~2.0.3", "codelyzer": "~4.5.0", "jasmine-core": "~2.99.1", "jasmine-spec-reporter": "~4.2.1", "karma": "~3.1.1", "karma-chrome-launcher": "~2.2.0", "karma-coverage-istanbul-reporter": "~2.0.1", "karma-jasmine": "~1.1.2", "karma-jasmine-html-reporter": "^0.2.2", "protractor": "~5.4.0", "ts-node": "~7.0.0", "tslint": "~5.11.0", "typescript": "~3.2.2" } }
Create Employee class - employee.ts
export class Employee {
id: number;
firstName: string;
lastName: string;
emailId: string;
active: boolean;
}
EmployeeService - employee-service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class EmployeeService {
private baseUrl = '/api/v1/employees';
constructor(private http: HttpClient) { }
getEmployee(id: number): Observable<Object> {
return this.http.get(`${this.baseUrl}/${id}`);
}
createEmployee(employee: Object): Observable<Object> {
return this.http.post(`${this.baseUrl}`, employee);
}
updateEmployee(id: number, value: any): Observable<Object> {
return this.http.put(`${this.baseUrl}/${id}`, value);
}
deleteEmployee(id: number): Observable<any> {
return this.http.delete(`${this.baseUrl}/${id}`, { responseType: 'text' });
}
getEmployeesList(): Observable<any> {
return this.http.get(`${this.baseUrl}`);
}
}
EmployeeListComponent - employee-list.component.ts
import { Observable } from "rxjs";
import { EmployeeService } from "./../employee.service";
import { Employee } from "./../employee";
import { Component, OnInit } from "@angular/core";
@Component({
selector: "app-employee-list",
templateUrl: "./employee-list.component.html",
styleUrls: ["./employee-list.component.css"]
})
export class EmployeeListComponent implements OnInit {
employees: Observable<Employee[]>;
constructor(private employeeService: EmployeeService) {}
ngOnInit() {
this.reloadData();
}
reloadData() {
this.employees = this.employeeService.getEmployeesList();
}
deleteEmployee(id: number) {
this.employeeService.deleteEmployee(id)
.subscribe(
data => {
console.log(data);
this.reloadData();
},
error => console.log(error));
}
}
Create a template for EmployeeListComponent - employee-list.component.html
<div class="panel panel-default">
<div class="panel-heading">
<h1>Employees</h1>
</div>
<div class="panel-body">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let employee of employees | async">
<td>{{employee.firstName}}</td>
<td>{{employee.lastName}}</td>
<td>{{employee.emailId}}</td>
<td><button (click)="deleteEmployee(employee.id)">Delete</button></td>
</tr>
</tbody>
</table>
</div>
</div>
CreateEmployeeComponent - create-employee.component.ts
import { EmployeeService } from './../employee.service';
import { Employee } from './../employee';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-create-employee',
templateUrl: './create-employee.component.html',
styleUrls: ['./create-employee.component.css']
})
export class CreateEmployeeComponent implements OnInit {
employee: Employee = new Employee();
submitted = false;
constructor(private employeeService: EmployeeService) { }
ngOnInit() {
}
newEmployee(): void {
this.submitted = false;
this.employee = new Employee();
}
save() {
this.employeeService.createEmployee(this.employee)
.subscribe(data => console.log(data), error => console.log(error));
this.employee = new Employee();
}
onSubmit() {
this.submitted = true;
this.save();
}
}
Create a template for EmployeeCreateComponent create-employee.component.html
<h3>Create Employee</h3>
<div [hidden]="submitted" style="width: 400px;">
<form (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="name">First Name</label>
<input type="text" class="form-control" id="firstName" required [(ngModel)]="employee.firstName" name="firstName">
</div>
<div class="form-group">
<label for="name">Last Name</label>
<input type="text" class="form-control" id="lastName" required [(ngModel)]="employee.lastName" name="lastName">
</div>
<div class="form-group">
<label for="name">Email ID</label>
<input type="text" class="form-control" id="emailId" required [(ngModel)]="employee.emailId" name="emailId">
</div>
<button type="submit" class="btn btn-success">Submit</button>
</form>
</div>
<div [hidden]="!submitted">
<h4>You submitted successfully!</h4>
</div>
Important: Note that update employee and view employee features covered in
Spring Boot + Angular 8 CRUD Example Tutorial.
EmployeeDetailsComponent- employee-details.component.ts
import { Employee } from './../employee';
import { Component, OnInit, Input } from '@angular/core';
import { EmployeeService } from '../employee.service';
import { EmployeeListComponent } from '../employee-list/employee-list.component';
@Component({
selector: 'app-employee-details',
templateUrl: './employee-details.component.html',
styleUrls: ['./employee-details.component.css']
})
export class EmployeeDetailsComponent implements OnInit {
@Input() employee: Employee;
constructor(private employeeService: EmployeeService, private listComponent: EmployeeListComponent) { }
ngOnInit() {
}
}
Create a template for EmployeeDetailsComponent employee-details.component.html
<div *ngIf="employee">
<div>
<label>Name: </label> {{employee.firstName}}
</div>
<div>
<label>Age: </label> {{employee.lastName}}
</div>
<div>
<label>Active: </label> {{employee.emailId}}
</div>
<div>
<label>Active: </label> {{employee.active}}
</div>
<span class="button is-small btn-primary" *ngIf='employee.active' (click)='updateActive(false)'>Inactive</span>
<span class="button is-small btn-primary" *ngIf='!employee.active' (click)='updateActive(true)'>Active</span>
<span class="button is-small btn-danger" (click)='deleteEmployee()'>Delete</span>
<hr/>
</div>
AppRoutingModule - app-routing.module.ts
import { EmployeeDetailsComponent } from './employee-details/employee-details.component';
import { CreateEmployeeComponent } from './create-employee/create-employee.component';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EmployeeListComponent } from './employee-list/employee-list.component';
const routes: Routes = [
{ path: '', redirectTo: 'employee', pathMatch: 'full' },
{ path: 'employees', component: EmployeeListComponent },
{ path: 'add', component: CreateEmployeeComponent },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
AppComponent - app/app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Angular 7 + Spring Boot 2 + Spring Data JPA + MySQL + CRUD Tutorial';
}
app/app.component.html
<div class="container">
<h2>{{title}}</h2>
<hr>
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<!-- Links -->
<ul class="navbar-nav">
<li class="nav-item">
<a routerLink="employees" class="btn btn-primary active" role="button" routerLinkActive="active">Employees</a>
</li>
<li class="nav-item" style="margin-left: 10px;">
<a routerLink="add" class="btn btn-primary active" role="button" routerLinkActive="active">Add</a>
</li>
</ul>
</nav>
<router-outlet></router-outlet>
</div>
app/app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CreateEmployeeComponent } from './create-employee/create-employee.component';
import { EmployeeDetailsComponent } from './employee-details/employee-details.component';
import { EmployeeListComponent } from './employee-list/employee-list.component';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [
AppComponent,
CreateEmployeeComponent,
EmployeeDetailsComponent,
EmployeeListComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Configure a proxy for your API calls with Angular CLI
this.http.get('http://locahost:8080/api/v1/employees') .map(res => res.json());
Configuring your Angular CLI dev-server proxy
- add the proper CORS headers - This is definitely a must in a case when you design a generic API where you don’t even know the consumer.
- use a proxy - A proxy is a piece of software which is in between your JavaScript/Angular app doing the Ajax request and your backend API. This is the choice to go in a classic app.
proxy.conf.json
{ "/api/v1/employees": { "target": "http://localhost:8080", "secure": false } }
Running Angular 7 Application
Let's run the above developed Angular App with a command: npm startNote that when you execute npm start, ng serve will be invoked which is a command to the CLI to fire up its internal development server.
Output
Open browser for URL - http://URLalhost:4200/:Employee List Page
Add Employee Page
Delete Employee
Important: Note that update employee and view employee features covered in
Spring Boot + Angular 8 CRUD Example Tutorial.
The source code of this article available on my GitHub repository at https://github.com/RameshMF/angular7-springboot-crud-tutorial
Related Java EE Tutorials
- Spring Boot 2 Tutorial
- Spring Core 5 Tutorial
- Spring Data JPA Tutorial
- Spring MVC 5 Tutorial
- Spring Security Tutorial
- Java Persistence API
- RabbitMQ Tutorial
- Hibernate ORM 5
- Eclipse Quick Tutorials
- Apache HttpClient Tutorial
- Apache Maven Tutorial
- JAX-RS Tutorial
- Jersey Rest Tutorial
- Spring Framework 5
Hi
ReplyDeleteyou did not show how to connect to the database
Added missing MySQL database configuration step. My suggestion is to clone source code from my GitHub repository.
Deletethank u very mch
DeleteRamesh fadatare
DeleteThat's great...
ReplyDeleteIt is an informative post.
ReplyDeletethank you ..
DeleteExcellent latest release of spring boot and angular 7 tutorial. Very informative article and very helpful. Thanks Ramesh.
ReplyDeleteThe codes found in your github (front and backend) are not working for me.
ReplyDeleteHi, what is the issue you are facing. Can you paste your error here so i that i will try to help you out.
DeleteThank you for your help! I'll send you an email with all the details and screens needed to describe the issues.
DeleteI'm having en error when I want to get an specific employee or when I want to delete. this is the error
ReplyDeleteI don't know what is happening.
Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'DELETE' not supported].
I'm calling directly the rest service using soapUi
Can you check you were selected DELETE http method in Soap UI.
DeleteThere is no detail of the exception classes so it doesnt compile, could you post those files?
ReplyDeleteHi Ness, I have added these exception classes to this post. You can download complete source code of this article from my GitHub repository (Link given at end of this article)
DeleteDo you have any crud design with lazy loading with nested and has a objects like personperson em manager relations...if so kindly post here
ReplyDeleteIn the create-employee.component.html the text of the label for the emailId input is 'First Name' instead of 'Email address'. Regards
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteare you following same project structure and code?. You can check out complete source code of this tutorial from my GitHub repository and try it - https://github.com/RameshMF/angular7-springboot-crud-tutorial
DeleteDescription:
DeleteI used your code structure without any change, I got this error. I killed the thread twice and again the same error I got.I think some connection issue may happen..
The Tomcat connector configured to listen on port 8080 failed to start. The port may already be in use or the connector may be misconfigured.
Action:
Verify the connector's configuration, identify and stop any process that's listening on port 8080, or configure this application to listen on another port.
"Verify the connector's configuration" - I didn't get this. I am using default embedded tomcat port 8080. If you are getting error like - the port may already be in use means you have already running this or other spring boot application on 8080 port. Many peoples using this source code and find useful so i don't think any configuration missing here. Do you want to give any suggestion anything here?
DeleteBackend is working fine now. cant get values from backend to frontend.
DeleteCan you paste some details about the issue or error so that i can able to help you.
DeleteI am having the same issue, backend is working fine but frontend is not connecting to backend and no error
Deleteerror: "Cannot GET /api/employees
ReplyDelete
headers: Object { normalizedNames: Map(0), lazyUpdate: null, lazyInit: lazyInit()
}
message: "Http failure response for http://localhost:4200/api/employees: 404 Not Found"
name: "HttpErrorResponse"
ok: false
status: 404
statusText: "Not Found"
url: "http://localhost:4200/api/employees"
: {…}
constructor: function HttpErrorResponse()
: Object { … }
core.js:15724
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: Æ’}
ReplyDeletemessage: "Http failure response for http://localhost:4200/api/emp/employees: 404 Not Found"
name: "HttpErrorResponse"
ok: false
status: 404
statusText: "Not Found"
url: "http://localhost:4200/api/emp/employees"
Its cross - origin error actually.Added @CrossOrigin(origins = { "http://localhost:4200" }) @ req controller.working fine.thank you
DeleteYou are welcome. I am glad that my tutorials are useful to you.
Deletei have the same error because there are not communication with backend and frontend
DeleteTo avoid CORS related issues and placing base URI at common place, i have configured proxy in this example. Please check out "Configure a proxy for your API calls with Angular CLI" step in above article.
DeleteUI and Backend integration not working getting 404 while request
ReplyDeleteTo avoid CORS related issues and placing base URI at common place, i have configured proxy in this example. Please check out "Configure a proxy for your API calls with Angular CLI" step in above article.
DeleteHello, I have following Error:
ReplyDelete"Http failure response for localhost:9080/filename/api: 0 unknown Error"
What went wrong?
To avoid CORS related issues and placing base URI at common place, i have configured proxy in this example. Please check out "Configure a proxy for your API calls with Angular CLI" step in above article.
DeletePerfect. Thanks
DeleteGreat tutorial dude, but when I trying test the REST API on Postman, got a message: "Status: 401 Unauthorized", I think this is about Spring Security, but I dont know how to fix this. Anyone can help me please? Thanks in advance !!! :)
ReplyDeleteCheck out proxy configuration step in this article.
Delete"start": "ng serve --proxy-config proxy.conf.json", in package.json fixed this for me.
Deletethe whole thing will not work by using ng serve, I have to use npm start. The different is npm start run a proxy so that the request will be pass to localhost:8080
ReplyDeleteSuper informative and complete example. Thank you for sharing it!
ReplyDeleteThank you Nick
DeleteIt's a good example, but it's not complete! Where is the edit-details functionality? I don't see a edit button in the employee-list :(
ReplyDeleteCheck out, I have added update employee component at Spring Boot + Angular 8 CRUD Example Tutorial
DeleteHow can you return to list component with data refreshed after doing an add?
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteFirstly I want to say thank for the tutorials. I am very interested learn angular and spring. And also I couldn't implemented employee update functionality. Could you please provide that coding part for me.
ReplyDeleteNice Article, Instead of mysql how can I integrate with hsqldb?
ReplyDeleteThanks, Yes, check out my article at https://www.javaguides.net/2019/01/configure-spring-boot-with-embedded-h2-hsql-and-derby-databases.html
DeleteGreat Article, congratulations.!
ReplyDeleteCheck out I have added update employee component at Spring Boot + Angular 8 CRUD Example Tutorial
DeleteHi, can you please help me with the update employee component?
ReplyDeletein your article you show how to create, delete and get employee.
i create new component (edit-employee) with the same form like create employee
but how i transfer the data of the specific employee to the new edit form.
thanks :)
I have added update employee component at Spring Boot + Angular 8 CRUD Example Tutorial
DeleteThis article is very helpful for beginner. Thank you for sharing your knowledge. I expect more from you in future.
ReplyDeleteAppreciate your work...