2.8 KiB
Creating and Using Services
Services in Angular are reusable pieces of code that handle data fetching, business logic, or state management that multiple components or other services need to access.
Creating a Service
You can generate a service using the Angular CLI:
ng generate service my-data
Or you can manually create a TypeScript class and decorate it with @Service().
import {Service} from '@angular/core';
@Service()
export class BasicDataStore {
private data: string[] = [];
addData(item: string): void {
this.data.push(item);
}
getData(): string[] {
return [...this.data];
}
}
The @Service decorator
Using @Service is the recommended approach for most services. It tells Angular to:
- Create a single instance (singleton) for the entire application.
- Make it available everywhere automatically, without needing to list it in any
providersarray. - Enable tree-shaking, meaning the service is only included in the final JavaScript bundle if it is actually injected somewhere.
The autoProvided option
If you don't want to create a singleton of your service, you can set @Service({autoProvided: false}) and declare the service a providers array.
Injecting a Service
Once a service is created, you can inject it into components, directives, or other services using the inject() function.
Injecting into a Component
import {Component, inject} from '@angular/core';
import {BasicDataStore} from './basic-data-store.service';
@Component({
selector: 'app-example',
template: `
<div>
<p>Data items: {{ dataStore.getData().length }}</p>
<button (click)="dataStore.addData('New Item')">Add Item</button>
</div>
`,
})
export class Example {
// Inject the service as a class field
dataStore = inject(BasicDataStore);
}
Injecting into Another Service
Services can inject other services in the exact same way.
import {Injectable, inject} from '@angular/core';
import {AdvancedDataStore} from './advanced-data-store.service';
@Service()
export class BasicDataStore {
// Injecting another service
private advancedDataStore = inject(AdvancedDataStore);
private data: string[] = [];
getData(): string[] {
// Combine data from this service and the injected service
return [...this.data, ...this.advancedDataStore.getData()];
}
}
Advanced Service Patterns
While @Service covers most scenarios, you may sometimes need:
- Component-specific instances: If a component needs its own isolated instance of a service, provide it directly in the component's
@Component({ providers: [MyService] })array and set theautoProvided: falseoption:@Service({autoProvided: false}) - Factory providers: For dynamic creation.
- Value providers: For injecting configuration objects.