Angular Services: Difference between revisions

From bibbleWiki
Jump to navigation Jump to search
Line 70: Line 70:
</syntaxhighlight>
</syntaxhighlight>
=Dependency Injection=
=Dependency Injection=
There are three methods to create instances of services
There are four methods to create instances of services
*UseClass
*UseClass
*UseExisting
*UseExisting
*UseValue
*UseValue
*UseFactory
==UseClass==
==UseClass==
A provider tells an injector how to create a service, for the long hand version of this it would look like this.
A provider tells an injector how to create a service, for the long hand version of this it would look like this.
Line 108: Line 109:
     }}
     }}
   ]
   ]
..
</syntaxhighlight>
==UseFactory==
We implement this by providing factory function to build an service. The deps is and array of parameters which may be required for the factory function.
The function
<syntaxhighlight lang="ts">
import { LoggerService } from "./logger.service";
import { DataService } from "./data.service";
export function dataServiceFactory(logger: LoggerService) {
  let dataService = new DataService(logger)
  logger.log(`Creating new Data Service with factory function`)
  return dataService
}
</syntaxhighlight>
And the service creation
<syntaxhighlight lang="ts">
@NgModule({
...
  providers: [
    LoggerService,
    { provide: DataService, useFactory: dataServiceFactory, deps: [LoggerService] }
  ],
..
..
</syntaxhighlight>
</syntaxhighlight>

Revision as of 02:40, 8 September 2020

Introduction

A Service is

  • Reusable piece of functionality
  • Responsibility for sing piece of function

Create a Service if

  • Not required by the view
  • Business logic not used across components
  • Share logic across components

Parts of a Service

  • Class
  • Injectable Decorator
  • Provider, defined in the module as an array

Delivering to a component is simple

Basic Service

Service Code

This is the old way to register a service. We specify the @Injectable decorator with no arguments

import {Injectable} from '@angular/core'
@Injectable()
export class LoggerService {

  log(message: string) : void {
    const timeString : string = new Date().toLocaleTimeString()
    console.log(`${message} (${timeString})`)
  }

  error(message: string) :void {
    console.error(`ERROR: ${message}`)
  }
}

The recommended way

import {Injectable} from '@angular/core'
@Injectable({
   providedIn: 'root'
})
export class LoggerService {
...
}

Registering the Service

This is not required provided you use the providedIn property in the @Injectable declaration and the benefit of not specifying it in the providers array is that the service is not compiled in if it is not determined as used.

...
import { LoggerService } from './services/logger.service';
...
@NgModule({
  declarations: [
...
  ],
  imports: [
...  ],
  providers: [LoggerService],
...

Usage Of Service Code

class AComponent {
...
   constructor(private loggerService : LoggerService) {}
..
   this.loggerService.log("Whoopee!")

Using CLI to create a Service

ng g s services/data --spec false

Dependency Injection

There are four methods to create instances of services

  • UseClass
  • UseExisting
  • UseValue
  • UseFactory

UseClass

A provider tells an injector how to create a service, for the long hand version of this it would look like this.

@NgModule({
...
  providers: [
     { provide: LoggerService, useClass: LoggerService}
  ]
..

UseExisting

We can specify an existing class in the hierarchy provided it has the correct interface.

@NgModule({
...
  providers: [
     PlainLogger,
     { provide: LoggerService, useExisting: PlainLogger}
  ]
..

UseValue

We implement these on the fly.

@NgModule({
...
  providers: [
     PlainLogger,
     { provide: LoggerService, useValue: {
       log: (message) => console.log(`MESSAGE": ${message}`),
       error: (message) => console.error(`ERROR": ${message}`)
     }}
  ]
..

UseFactory

We implement this by providing factory function to build an service. The deps is and array of parameters which may be required for the factory function. The function

import { LoggerService } from "./logger.service";
import { DataService } from "./data.service";

export function dataServiceFactory(logger: LoggerService) {

  let dataService = new DataService(logger)

  logger.log(`Creating new Data Service with factory function`)

  return dataService
}

And the service creation

@NgModule({
...
  providers: [
    LoggerService,
    { provide: DataService, useFactory: dataServiceFactory, deps: [LoggerService] }
  ],
..