Tuesday, March 14, 2023

Service in Angular With Examples

A good design always advocates “Separation of concerns”, in Angular too that is desirable thus it is recommended that a Component should have only view-related functionality. Any application logic like fetching data through server calls, user input validation, logging to console should be delegated to a service in Angular.


Benefits of using Services in Angular

By delegating such tasks to services you have the following advantages.

  • Having lean components (concentrating only on enabling user experience).
  • Application logic in service classes that can be made available to any component thus promoting reusability.
Service in Angular

How to create a service in Angular

You can create an Angular service using following command.

ng generate service service_name

or you can use the short form of it.

ng g s service_name

For example if you want to create a service class logger inside services folder in your app directory.

ng g s services/logger

This will create logger.service.ts TypeScript file with in services folder.

Angular service example

Lets create the same logger service example. If you want to create your service classes with in a services folder then run the following command to create logger service.

ng g s services/logger

Angular CLI creates a logger.service.ts file and also do the following-

  1. Adds @Injectable decorator
  2. Registers a provider with the root injector
    @Injectable({
      providedIn: 'root'
    })
    
    

Add code for logging to console in the service class.

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

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

  constructor() { }
  log(msg: string) { 
    console.log(msg); 
  }
  error(msg: string) { 
    console.error(msg); 
  }
}

Component class

Let’s create a component user.component.ts where we’ll use this LoggerService.

import { Component, OnInit } from '@angular/core';
import { User } from './user.model';
import { LoggerService } from '../services/logger.service';

@Component({
  selector: 'app-user',
  templateUrl: './',
  styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {
  users: User[];
  constructor(private loggerService: LoggerService) { 
    // Adding user instances in the users array
    this.users = [new User('Jack', 62, new Date('2005-03-25')),
                  new User('Olivia', 26, new Date('2014-05-09')),
                  new User('Manish', 34, new Date('2010-10-21'))] ;

    this.loggerService.log(`Total ${this.users.length} users in array.`);
  }

  ngOnInit(): void {
  }
}

In the constructor of the component you can see that an instance of LoggerService is created which is injected by the Angular (see the next section for more details about dependency injection). You also need to import the logger.service class.

Once the service instance is available that can be used to log a message, that’s what the following statement does in the code.

this.loggerService.log(`Total ${this.users.length} users in array.`);

Template (HTML file)

Let’s quickly create user.component.html file too which shows all the users in a table.

<div class="container">
  <h2>User Details</h2>
  <table class="table table-sm table-bordered m-t-4">
    <tr>
      <th>Name</th>
      <th>Age</th>
      <th>Joining Date</th>
    </tr>
    <tr *ngFor="let user of users">
      <td>{{user.name}}</td>
      <td>{{user.age}}</td>
      <td>{{user.joinDate | date:'dd/MM/yyyy'}}</td>
    </tr>
  </table>
</div>

Now when you run it, you can see the message in the console.

Angular Service example

Service and dependency injection in Angular

You would have noticed in the example that Component class has a dependency on a LoggerService instance but that is not created explicitly. So you don’t see code as given below-

export class UserComponent implements OnInit {
  users: User[];
  loggerService: LoggerService; 
  constructor() { 
    this.loggerService = new LoggerService();
    ..
  }
..
}

Angular uses the concept of dependency injection to inject the dependencies. DI is a coding pattern in which class dependencies are injected rather than class creating them itself. In Angular, the DI framework provides declared dependencies to a class when that class is instantiated. The whole DI process in Angular can be explained in simple steps as follows-

  1. Create and register a dependency with Angular.
  2. Configure how the dependency instance is created and injected.
  3. Inject the dependency where needed.

1. Create and register a dependency with Angular

In case of providing Service as dependency first step is to create an injectable service class. To define a class as a service in Angular, decorate the class with @Injectable() decorator to provide the metadata that allows Angular to inject it into a component as a dependency.

2. Configure how the dependency instance is created and injected

Using @Injectable() decorator you just mark a service that can be injected. You also need to configure an Angular dependency injector with a provider of that service to actually inject a service.

The injector is responsible for creating service instances and injecting them into component classes. But you don't need to create injector yourself that is done by Angular itself and the first injector Angular creates is the 'root injector' that it creates during the bootstrap process.

A provider tells an injector how to create the service. You must configure an injector with a provider before that injector can create a service.

If we take our Service class there the @Injectable decorator is used like-

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

@Injectable() decorator has the ‘providedIn’ metadata option, where provider of the decorated service class is specified as root injector.

When a service is provided at the root level, Angular creates a single, shared instance of the Service and injects it into any class that asks for it. So LoggerService is a singleton service and the same instance will be injected where it is asked for.

You can register a provider using other ways too. Check this post for other options- Injector Hierarchy and Service Instances in Angular

3. Inject the dependency

When you need a Service in a Component you ask for Service to be injected, rather than creating new instance yourself. You can tell Angular to inject a dependency in a component's constructor by specifying a constructor parameter with the dependency type.

That is why constructor in UserComponent has LoggerService type as parameter.

constructor(private loggerService: LoggerService)

That's all for this topic Service in Angular With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Angular Tutorial Page


Related Topics

  1. Injector Hierarchy and Service Instances in Angular
  2. Angular - Call One Service From Another
  3. Angular Project Structure With File Description
  4. Creating New Component in Angular
  5. How to Add Bootstrap to Angular Application

You may also like-

  1. Angular CanActivateChild Guard to protect Child Routes
  2. Angular @Component Decorator
  3. Angular Custom Property Binding Using @Input Decorator
  4. Angular ngSwitch Directive With Examples
  5. Installing Anaconda Distribution On Windows
  6. @FunctionalInterface Annotation in Java
  7. Java ReentrantLock With Examples
  8. Spring WebFlux Example Using Annotation-Based Programming - Spring Web Reactive

No comments:

Post a Comment