What are Services in Angular?
In Angular, Services are singleton (having a single instance) classes that provide specific functionality or handle common logic in an Angular application, which can be used throughout the entire application.
In a single Angular application, one or more services can be used. Similarly, an Angular component may depend on one or more services.
Angular services may depend on other services to work properly. Dependency resolution is one of the complex and time-consuming activities in developing any application. To reduce this complexity, Angular provides Dependency Injection (a design pattern) as one of its core concepts.

Key Elements of a Service Class
As we define the component in angular, services also include the following:
- A TypeScript decorator that declares the class as an Angular service via @Injectable (i.e., is a decorator) and allows you to define what part of the application can access the service via the providedIn property (which is by default ‘root’) to allow the service to access throughout the entire application.
- A TypeScript class (or say service) that defines the desired code that will be accessible when the service is injected into another components, directive, etc.
Here is a basic example of the printName service:
import{Injectable}from'@angular/core';@Injectable({providedIn:'root'})exportclassprintName{display(name:string){return name;}}
Creating Angular Service
An Angular service is a plain TypeScript class with one or more methods (functionality) along with the @Injectable decorator. This decorator allows the normal TypeScript class to be used as a service in an Angular application.
To create a service in an Angular application, run the following command in your IDE’s terminal −
ng generate service service-name or ng generate service Services/service-name
Here, the first command will create a service class directly in your Angular application without a separate folder, which can be a bit confusing. However, the second command will create a ‘Services’ folder and place the service class inside it.
After executing the second command, the following will be displayed in your IDE’s terminal −
CREATE src/app/Services/print-name.service.spec.ts(389 bytes)CREATE src/app/Services/print-name.service.ts(147 bytes)
The printName service is as follows −
import{ Injectable }from'@angular/core';@Injectable({ providedIn:'root'})exportclassPrintNameService{//define it after the service is created..display(name:string){return name;}constructor(){}}
Here, @Injectable decorator converts a plain Typescript class into Angular service.
How to use a Service?
When you want to use a service in a component, you need to −
- Import the service in the component where you want to use it.
- Declare a class field where the service needs to be injected.
- Assign the class field to the instance of the service created by Angular’s dependency injection.
Here is what it might look like in the User component −
import{ Component, inject }from'@angular/core';import{ PrintNameService }from'../Services/print-name.service';import{ CommonModule }from'@angular/common';@Component({ selector:'app-user', standalone:true, imports:[PrintNameService, CommonModule], templateUrl:'./user.component.html', styleUrl:'./user.component.css'})exportclassUserComponent{private print_name =inject(PrintNameService); my_name =this.print_name.display("John");}
In this example, the printName service is being used by calling the Angular function inject and passing in the service to it.
How Service Works?
Here are the key concepts about how services work in Angular −Service Registration
- When you define a service with @Injectable({ providedIn: ‘root’ }), Angular registers it with the root injector.
- This means the service is available for injection throughout the entire application.
Service Injection
- When a component (or another service) requires the service, then the Angular DI (dependency injection) mechanism creates an instance of the service and injects it into the requesting component/service.
Singleton Pattern
- Services provided at the root level (providedIn: ‘root’) are singletons by default. This means there is only one instance of the service throughout the entire application, which ensures a consistent state and shared data.
Register Angular service
To use Dependency Injection, every service needs to be registered into the system. Angular provides multiple option to register a service. They are as follows −
- ModuleInjector @ root level
- ModuleInjector @ platform level
- ElementInjector using providers meta data
- ElementInjector using viewProviders meta data
- NullInjector
ModuleInjector @ root
ModuleInjector enforces the service to used only inside a specific module. ProvidedInmeta data available in @Injectable has to be used to specify the module in which the service can be used.
The value should refer to the one of the registered Angular Module (decorated with @NgModule). root is a special option which refers the root module of the application. The sample code is as follows −
import{ Injectable }from'@angular/core';@Injectable({ providedIn:'root',})exportclassDebugService{constructor(){}}
ModuleInjector @ platform
Platform Injector is one level higher than ModuleInject and it is only in advanced and rare situation. Every Angular application starts by executing PreformBrowserDynamic().bootstrap method (see main.js), which is responsible for bootstrapping root module of Angular application.
PreformBrowserDynamic() method creates an injector configured by PlatformModule. We can configure platform level services using platformBrowser() method provided by PlatformModule.
NullInjector
NullInjector is one level higher than platform level ModuleInjector and is in the top level of the hierarchy. We could not able to register any service in the NullInjector. It resolves when the required service is not found anywhere in the hierarchy and simply throws an error.
ElementInjector using providers
ElementInjector enforces the service to be used only inside some particular components. providers and ViewProviders meta data available in @Component decorator is used to specify the list of services to be visible for the particular component. The sample code to use providers is as follows −
ExpenseEntryListComponent
// import statement import{ DebugService }from'../debug.service';// component decorator @Component({ selector:'app-expense-entry-list', templateUrl:'./expense-entry-list.component.html', styleUrls:['./expense-entry-list.component.css'], providers:[DebugService]})
Here, DebugService will be available only inside the ExpenseEntryListComponent and its view. To make DebugService in other component, simply use providers decorator in necessary component.
ElementInjector using viewProviders
viewProviders is similar to provider except it does not allow the service to be used inside the componentââ¬â¢s content created using ng-content directive.
ExpenseEntryListComponent
// import statement import{ DebugService }from'../debug.service';// component decorator @Component({ selector:'app-expense-entry-list', templateUrl:'./expense-entry-list.component.html', styleUrls:['./expense-entry-list.component.css'], viewProviders:[DebugService]})
Parent component can use a child component either through its view or content. Example of a parent component with child and content view is mentioned below −
Parent component view / template
<div> child template in view <child></child></div><ng-content></ng-content>
child component view / template
<div> child template in view </div>
Parent component usage in a template (another component)
<parent><!-- child template in content --><child></child></parent>
Here,
- child component is used in two place. One inside the parentâs view. Another inside parent content.
- Services will be available in child component, which is placed inside parentâs view.
- Services will not be available in child component, which is placed inside parentâs content.
Resolve Angular service
Let us see how a component can resolve a service using the below flow diagram.

Here,
- First, component tries to find the service registered using viewProviders meta data.
- If not found, component tries to find the service registered using providers meta data.
- If not found, Component tries to find the service registered using ModuleInjector
- If not found, component tries to find the service registered using PlatformInjector
- If not found, component tries to find the service registered using NullInjector, which always throws error.
The hierarchy of the Injector along with work flow of the resolving the service is as follows −
