Service
Service is a broad category encompassing any value, function, or feature that an app needs.
For data or logic that is not associated with a specific view, and that you want to share across components, you create a service class.
A service class definition is immediately preceded by the @Injectable
decorator.
The decorator provides the metadata that allows your service to be injected into client components as a dependency.
Distinguishes Components from Services
component's job
enable the user experience and nothing more
present properties and methods for data binding, in order to mediate between the view (rendered by the template) and the application logic (which often includes some notion of a model).
not component's job (can delegate such tasks to services)
define how to fetch data from the server
validate user input
log directly to the console
By defining that kind of processing task in an injectable service class, you make it available to any component.
You can also make your app more adaptable by injecting different providers of the same kind of service, as appropriate in different circumstances.
Injector
Angular creates an application-wide injector for you during the bootstrap process.
The injector maintains a container of dependency instances that it has already created, and reuses them if possible.
For any dependency you need in your app, you must register a provider with the app's injector, so that the injector can use it to create new instances.
When Angular creates a new instance of a component class, it determines which services or other dependencies that component needs by looking at the types of its constructor parameters.
For example, the constructor of HeroListComponent needs a HeroService:
When Angular discovers that a component depends on a service, it first checks if the injector already has any existing instances of that service. If a requested service instance does not yet exist, the injector makes one using the registered provider, and adds it to the injector before returning the service to Angular.
Why do we need Service
Components shouldn't fetch or save data directly and they certainly shouldn't knowingly present fake data. They should focus on presenting data and delegate data access to a service.
Services are a great way to share information among classes that don't know each other.
The @Injectable() decorator tells Angular that this service might itself have injected dependencies.
Provide the Service
You must provide the HeroService in the dependency injection system before Angular can inject it into the HeroesComponent
There are several ways to provide the HeroService: in the HeroesComponent, in the AppComponent, in the AppModule. Each option has pros and cons.
src/app/app.module.ts (providers)
The providers array tells Angular to create a single, shared instance of HeroService and inject into any class that asks for it.
Where to Inject & call Service
Inject
Angular will inject the singleton MessageService into that property when it creates the HeroService.
Reserve the constructor for simple initialization such as wiring constructor parameters to properties. The constructor shouldn't do anything. It certainly shouldn't call a function that makes HTTP requests to a remote server as a real data service would.
call
How to Call: Synchronous v.s Asynchronous
The HeroService.getHeroes() method has a synchronous
signature, which implies that the HeroService can fetch heroes synchronously.
This will not work in a real app. The assignment occurs synchronously, as if the server could return heroes instantly or the browser could freeze the UI while it waited for the server's response.
You're getting away with it now because the service currently returns mock heroes. But soon the app will fetch heroes from a remote server, which is an inherently asynchronous
operation.
HeroService.getHeroes() must have an asynchronous signature of some kind. It can take a callback. It could return a Promise
. It could return an Observable
.
In the HTTP tutorial, you'll call HttpClient.get<Hero[]>() which also returns an Observable<Hero[]> that emits a single value, an array of heroes from the body of the HTTP response.
Last updated
Was this helpful?