Angular Services

What is a Service?

  • Implemented using simple classes

  • Use @Injectable decorator

  • Used to

    • load data

    • validation

    • logging

Creating a Service

users.service.ts
import { Injectable } from '@angular/core';

@Injectable()
export class UserService {
  users = ['Bob', 'Mike', 'Jim'];

  getUsers(): string[] {
    return this.users;
  }
}

Dependency Injection

  • Common programming technique

  • Services are supplied to components using it

  • DI allows:

    • Using classes without hard coding constructor calls

    • Loose coupling

    • Substitute mocked services during testing

Bad:

users.service.ts
import { Component } from '@angular/core';
import { UserService } from './user.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  userService = new UserService();
}

Good:

app.component.ts
import { Component } from '@angular/core';
import { UserService } from './user.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  constructor(private userService: UserService) {}
}

Services in Components

  • Components get services through DI

  • Each component has it's own Injector to do DI

  • Injectors can only inject services they know about.

  • Injectors are notified of services via the component's providers meta data

  • Injectors are hierarchical, just like components and modules

  • If a component doesn't provide the service, it goes up the parent tree until it finds it or throws an error.

Best practice: don't use the component's providers to provide services. Provide it in a module or use ProvidedIn.

ProvidedIn:@Injectable({providedIn: 'root'})providedIn here tells Angular that the root injector is responsible for creating an instance of the service. Services that are provided this way are automatically made available to the entire application and don't need to be listed in any module.

DI with @Host or @Optional

// standard
constructor(private userService: UserService){}

// Restrict Injector hierarchy search to the parent
constructor(@Host() private userService: UserService){}

// Return null if provider not found (instead of throwing an error)
constructor(@Optional() private userService: UserService){}

The @Host() decorator limits the hierarchy search up to the parent component injector. If not found, will throw an error. The @Optional() decorator returns null if the provider is not found in the hierarchy tree instead of throwing an error.

Summary

  • What is a service

  • Creation of services

  • What is DI

  • Services in Components

  • DI decorators

Last updated