Dependency injection in Angular - Angular Service Example

In this article, we will learn how to create Angular service and how to use it in Angular components with an example.

Services are special components that are reusable throughout your app. We're going to create a service for the purpose of communicating with an API to fetch some data and display it on our lists page.

Quick Overview of Dependency injection (DI) in Angular

Dependency Injection is wired into the Angular framework and used everywhere to provide new components with the services or other things they need. Components consume services; that is, you can inject a service into a component, giving the component access to that service class.

To define a class as a service in Angular, use the @Injectable() decorator to provide the metadata that allows Angular to inject it into a component as a dependency. Similarly, use the @Injectable() decorator to indicate that a component or other class (such as another service, a pipe, or a NgModule) has a dependency.
Read more about DI at https://angular.io/guide/architecture-services.
Here are the steps to create and use Angular service:
1. Create Angular service - EmployeeService
2. Configure provider for service - default provider (root)
3. Inject service in component - CreateEmployeeComponent

Services are a great way to share information among classes that don't know each other.

1. Create Service - EmployeeService

Let's generate the service with the Angular CLI:
- ng g s employee
Notice "g s", these are just shorthand terms for "generate service". The name we're giving this service is "employee".

Let's visit the new service file located at /src/app/employee.service.ts:

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

@Injectable({
  providedIn: 'root',
})
export class EmployeeService {

  constructor() { }

}

Notice that the new service imports the Angular Injectable symbol and annotates the class with the @Injectable() decorator. This marks the class as one that participates in the dependency injection system. The EmployeeService class is going to provide an injectable service, and it can also have its own injected dependencies.

The EmployeeService will be used to get the data from the backend by calling spring boot APIs. Update the employee.service.ts file inside src/app directory with the following code to it -
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class EmployeeService {

  private baseUrl = 'http://localhost:8080/springboot-crud-rest/api/v1/employees';

  constructor(private http: HttpClient) { }

  getEmployee(id: number): Observable<any> {
    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}`);
  }
}
Here is a complete example at https://www.javaguides.net/2019/06/spring-boot-angular-7-crud-example-tutorial.html

2. Provide the EmployeeService

You must make the EmployeeService available to the dependency injection system before Angular can inject it into the CreateEmployeeComponent by registering a provider. A provider is something that can create or deliver a service; in this case, it instantiates the EmployeeService class to provide the service.

By default, the Angular CLI command ng generate service registers a provider with the root injector for your service by including provider metadata, that is providedIn: 'root' in the @Injectable() decorator.

@Injectable({
  providedIn: 'root',
})

3. Inject EmployeeService in CreateEmployeeComponent

Path - src/app/create-employee/create-employee.component.ts
CreateEmployeeComponent is used to create and handle a new employee form data. Add the following code to it -
import { EmployeeService } from '../employee.service';
import { Employee } from '../employee';
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

@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,
    private router: Router) { }

  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();
    this.gotoList();
  }

  onSubmit() {
    this.submitted = true;
    this.save();    
  }

  gotoList() {
    this.router.navigate(['/employees']);
  }
}
From the above code, it is clear that we are injecting EmployeeService into CreateEmployeeComponent:
  constructor(private employeeService: EmployeeService,
    private router: Router) { }

Comments