iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Create a TypeScript class for reusable behavior, provide it at the scope where it should live, then inject it into a component or another service. For the current unversioned Angular guide, the root-provided shorthand is @Service(); Angular v20 documentation uses @Injectable({ providedIn: 'root' }). Match the syntax to the Angular version you are using.
What an Angular service does
A service is a reusable class for logic that more than one part of an application may need, such as data access or business rules. Angular describes services as “reusable pieces of code that you can share across your application.” Angular’s service guide
Create the service
Generate it with Angular CLI
From your Angular project, run:
ng generate service CUSTOM_NAME
The CLI creates a TypeScript file for the service. Replace CUSTOM_NAME with a descriptive name, such as data-store. You can also create the class and file yourself.
Choose the decorator that matches your Angular version
The current unversioned Angular guide presents @Service() as shorthand for a root-provided service:
#1 Best Overall
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];
}
}
For this form, @Service() provides the service at the application root by default. The versioned Angular v20 guide instead documents the established @Injectable form:
import { Injectable } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class BasicDataStore {
// Reusable application logic goes here.
}
Use the syntax documented for your target Angular version rather than assuming these APIs are interchangeable across every release. The official guides do not establish a precise release boundary for @Service. See the Angular v20 service guide.
Rank #2
Inject the service into a consumer
In a valid injection context, such as a component or service field initializer, the current guide uses Angular’s inject() function:
import { Component, inject } from '@angular/core';
import { BasicDataStore } from './basic-data-store';
@Component({
selector: 'app-example',
template: '<button (click)="save()">Save</button>'
})
export class ExampleComponent {
private readonly store = inject(BasicDataStore);
save(): void {
this.store.addData('example');
}
}
With @Service, use inject() to obtain dependencies. If your code uses constructor injection, or needs advanced provider configuration, retain @Injectable as appropriate; Angular’s current guide calls out those cases.
Rank #3
Choose the service’s provider scope
Provisioning determines which injector can supply a service and whether consumers share an instance or receive a scoped one.
Root scope for an application-wide instance
providedIn: 'root' makes a service available through the root injector, so consumers resolve the shared application-level instance. The current @Service() shorthand also provides at root by default.
Rank #4
Local scope for a separate instance
Register a service in a component’s providers array when that component should have an instance associated with its injector. Providers can also be configured on directives, routes, or application configuration. Local provisioning is useful when a consumer needs its own instance, a more specific lifetime, or runtime configuration. For example:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
@Component({
selector: 'app-editor',
template: '<!-- editor view -->',
providers: [BasicDataStore]
})
export class EditorComponent {
private readonly store = inject(BasicDataStore);
}
A class marked with @Injectable() but without automatic provisioning still needs to be registered with the relevant provider configuration. For provider options such as useClass, useValue, useExisting, or useFactory, consult Angular’s dependency provider guide.
Use an InjectionToken for non-class dependencies
Dependencies such as configuration values, functions, or primitives are not classes that Angular can use directly as provider tokens. Define an InjectionToken to give the dependency a unique token; a token can also define a factory for automatic provision. Angular documents this and other dependency-injection options in its dependency injection guide.
Troubleshoot common injection errors
- “No provider” or unavailable-provider errors: Check that the service is registered at the injector scope where it is requested. A class decorator alone does not make a service available everywhere.
inject()called outside an injection context: Move the call to a supported context, such as a component or service field initializer, or use the injection pattern supported by the code and Angular version.- Unexpectedly separate service state: Check for a local provider that creates a component- or route-scoped instance instead of using the root-shared instance.
Angular’s injection-context guide explains where inject() is valid; its DI troubleshooting guide covers provider-resolution failures.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

