Skip to content

Commit 7f28c34

Browse files
committed
fix: migrate new files
1 parent 82ed555 commit 7f28c34

File tree

19 files changed

+2363
-0
lines changed

19 files changed

+2363
-0
lines changed
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
# Creating an injectable service
2+
3+
Service is a broad category encompassing any value, function, or feature that an application needs.
4+
A service is typically a class with a narrow, well-defined purpose.
5+
A component is one type of class that can use DI.
6+
7+
Angular distinguishes components from services to increase modularity and reusability.
8+
By separating a component's view-related features from other kinds of processing, you can make your component classes lean and efficient.
9+
10+
Ideally, a component's job is to enable the user experience and nothing more.
11+
A component should present properties and methods for data binding, to mediate between the view (rendered by the template) and the application logic (which often includes some notion of a model).
12+
13+
A component can delegate certain tasks to services, such as fetching data from the server, validating user input, or logging directly to the console.
14+
By defining such processing tasks in an injectable service class, you make those tasks available to any component.
15+
You can also make your application more adaptable by configuring different providers of the same kind of service, as appropriate in different circumstances.
16+
17+
Angular does not enforce these principles.
18+
Angular helps you follow these principles by making it easy to factor your application logic into services and make those services available to components through DI.
19+
20+
## Service examples
21+
22+
Here's an example of a service class that logs to the browser console:
23+
24+
<docs-code header="logger.service.ts (class)" language="typescript">
25+
export class Logger {
26+
log(msg: unknown) { console.log(msg); }
27+
error(msg: unknown) { console.error(msg); }
28+
warn(msg: unknown) { console.warn(msg); }
29+
}
30+
</docs-code>
31+
32+
Services can depend on other services.
33+
For example, here's a `HeroService` that depends on the `Logger` service, and also uses `BackendService` to get heroes.
34+
That service in turn might depend on the `HttpClient` service to fetch heroes asynchronously from a server:
35+
36+
<docs-code header="hero.service.ts" language="typescript"
37+
highlight="[7,8,12,13]">
38+
import { inject } from "@angular/core";
39+
40+
export class HeroService {
41+
private heroes: Hero[] = [];
42+
43+
private backend = inject(BackendService);
44+
private logger = inject(Logger);
45+
46+
async getHeroes() {
47+
// Fetch
48+
this.heroes = await this.backend.getAll(Hero);
49+
// Log
50+
this.logger.log(`Fetched ${this.heroes.length} heroes.`);
51+
return this.heroes;
52+
}
53+
}
54+
</docs-code>
55+
56+
## Creating an injectable service with the CLI
57+
58+
The Angular CLI provides a command to create a new service. In the following example, you add a new service to an existing application.
59+
60+
To generate a new `HeroService` class in the `src/app/heroes` folder, follow these steps:
61+
62+
1. Run this [Angular CLI](/tools/cli) command:
63+
64+
<docs-code language="sh">
65+
ng generate service heroes/hero
66+
</docs-code>
67+
68+
This command creates the following default `HeroService`:
69+
70+
<docs-code header="heroes/hero.service.ts (CLI-generated)" language="typescript">
71+
import { Injectable } from '@angular/core';
72+
73+
@Injectable({
74+
providedIn: 'root',
75+
})
76+
export class HeroService {}
77+
</docs-code>
78+
79+
The `@Injectable()` decorator specifies that Angular can use this class in the DI system.
80+
The metadata, `providedIn: 'root'`, means that the `HeroService` is provided throughout the application.
81+
82+
Add a `getHeroes()` method that returns the heroes from `mock.heroes.ts` to get the hero mock data:
83+
84+
<docs-code header="heroes/hero.service.ts" language="typescript">
85+
import { Injectable } from '@angular/core';
86+
import { HEROES } from './mock-heroes';
87+
88+
@Injectable({
89+
// declares that this service should be created
90+
// by the root application injector.
91+
providedIn: 'root',
92+
})
93+
export class HeroService {
94+
getHeroes() {
95+
return HEROES;
96+
}
97+
}
98+
</docs-code>
99+
100+
For clarity and maintainability, it is recommended that you define components and services in separate files.
101+
102+
## Injecting services
103+
104+
To inject a service as a dependency into a component, you can declare a class field representing the dependency and use Angular's `inject` function to initialize it.
105+
106+
The following example specifies the `HeroService` in the `HeroListComponent`.
107+
The type of `heroService` is `HeroService`.
108+
109+
<docs-code header="heroes/hero-list.component.ts" language="typescript">
110+
import { inject } from "@angular/core";
111+
112+
export class HeroListComponent {
113+
private heroService = inject(HeroService);
114+
}
115+
</docs-code>
116+
117+
It is also possible to inject a service into a component using the component's constructor:
118+
119+
<docs-code header="heroes/hero-list.component.ts (constructor signature)" language="typescript">
120+
constructor(private heroService: HeroService)
121+
</docs-code>
122+
123+
The `inject` method can be used in both classes and functions, while the constructor method can naturally only be used in a class constructor. However, in either case a dependency may only be injected in a valid [injection context](guide/di/dependency-injection-context), usually in the construction or initialization of a component.
124+
125+
## Injecting services in other services
126+
127+
When a service depends on another service, follow the same pattern as injecting into a component.
128+
In the following example, `HeroService` depends on a `Logger` service to report its activities:
129+
130+
<docs-code header="heroes/hero.service.ts" language="typescript"
131+
highlight="[3,9,12]">
132+
import { inject, Injectable } from '@angular/core';
133+
import { HEROES } from './mock-heroes';
134+
import { Logger } from '../logger.service';
135+
136+
@Injectable({
137+
providedIn: 'root',
138+
})
139+
export class HeroService {
140+
private logger = inject(Logger);
141+
142+
getHeroes() {
143+
this.logger.log('Getting heroes.');
144+
return HEROES;
145+
}
146+
}
147+
</docs-code>
148+
149+
In this example, the `getHeroes()` method uses the `Logger` service by logging a message when fetching heroes.
150+
151+
## What's next
152+
153+
<docs-pill-row>
154+
<docs-pill href="/guide/di/dependency-injection-providers" title="Configuring dependency providers"/>
155+
<docs-pill href="/guide/di/dependency-injection-providers#using-an-injectiontoken-object" title="`InjectionTokens`"/>
156+
</docs-pill-row>

0 commit comments

Comments
 (0)