Welcome to the tutorial on using @Self
, @SkipSelf &
Optional
decorators in Angular!
In this tutorial, you will gain a deep understanding of the various ways to configure the injector in Angular and how to effectively utilize the @Self
, @SkipSelf &
Optional
decorators.
We will dive into real-world examples and scenarios, providing you with the knowledge and skills to confidently and expertly use these decorators in your own projects.
By the end of this tutorial, you will have a good foundation in dependency injection with Angular and be able to configure the DI Framework to resolve the dependencies.
Let’s get started!
Table of Contents
How The DI framework Resolves Dependencies ?
We have previously covered Dependency Injection in more detail in other tutorials. In case you missed it or would like to review the information, here is a brief overview of how Dependency Injection works in Angular:
The Dependency Injection (DI) framework in Angular is a powerful tool that helps to manage the dependencies needed by components throughout an application.
When a component requests a dependency, the DI framework follows a specific process to resolve it.
First, it searches for the dependency within the current component’s ElementInjector
. If it is not found there, the request is passed up the injector hierarchy to the parent component’s ElementInjector
.
This process continues until either a provider is found or the root ElementInjector
is reached.
If the dependency is not found within the ElementInjector
hierarchy, the DI framework will then search for it within the ModuleInjector
hierarchy.
If the dependency cannot be found within either the ElementInjector
or ModuleInjector
hierarchies, an error will be thrown.
Through this process, the DI framework ensures that dependencies are properly provided to components in an Angular application
What is @Self decorator in Angular ?
In Angular, We use the decorator @Self
to indicate that the dependency should be injected using the current element injector rather than the parent injector.
This can be useful when you want to override a dependency that is provided by the parent injector, or when you want to ensure that the injector of the current element must be used to provide the dependency.
It can also be useful when you want to test a component in isolation and need to provide mock dependencies
@Self decorator Example
Here is a real-world example of using the @Self
decorator in Angular:
Imagine you are building a large application with several components that all use a service called UserService
to fetch user data.
The UserService
has a method called getUser()
that returns the currently logged-in user.
In your application, you have a component called ProfileComponent
that displays the user’s profile information.
You want this component to use its own instance of UserService
so that it can fetch the user data from a local cache, rather than making a network request.
To do this, you can provide a local provider for UserService
in the ProfileComponent
and use the @Self
decorator to inject the local instance of the service:
import { Component, Self } from '@angular/core';
@Component({
selector: 'app-profile',
template: '...',
providers: [{ provide: UserService, useClass: CachedUserService }]
})
export class ProfileComponent {
constructor(@Self() public userService: UserService) {}
}
In this example, the ProfileComponent
is using a provider for UserService
that uses the CachedUserService
class.
This means that the ProfileComponent
will have its own instance of UserService
that is provided by the CachedUserService
.
By using the
@Self
decorator, the component will inject its own instance of the service, rather than using the parent injector.
What is @SkipSelf decorator in Angular ?
In Angular, the @SkipSelf decorator indicates that a dependency must be injected from the parent injector, rather than the current element’s own injector.
This is useful when you need to access a dependency provided by a parent element but don’t want to risk the current element’s injector having a matching provider.
Remember that the @SkipSelf decorator only checks the parent injector for the dependency. The injector will throw an error if the dependency is not detected there..
@SkipSelf decorator Example
Here is an example of using the @SkipSelf
decorator in Angular:
Imagine you are developing a large application with many components.
All these component are using a service called LoggingService
to sends a message to the console.
In your application, you have a component called ChildComponent
that is used inside a parent component called ParentComponent
.
You want the ChildComponent
to use the LoggingService
provided by the ParentComponent
, rather than using its own instance of the service.
To do this, you can use the @SkipSelf
decorator to inject the LoggingService
from the parent component’s injector:
import { Component, SkipSelf } from '@angular/core';
@Component({
selector: 'app-child',
template: '...'
})
export class ChildComponent {
constructor(@SkipSelf() public loggingService: LoggingService) {}
}
To do this, you can use the @SkipSelf
decorator to inject the LoggingService
from the parent component’s injector:
What is @Optional decorator in angular ?
To indicate that a dependency is optional in Angular, we can use the @Optional
decorator.
This implies that the injector will not generate an error if the dependency cannot be located in the injector hierarchy. (Null will be injected as a dependency).
For example, consider the following component:
@Component({
selector: 'app-example',
template: '...'
})
export class ExampleComponent {
constructor(@Optional() public myService: MyService) {}
}
The @Optional
decorator is being used by the component in this example to indicate that the dependency on the myService
is optional.
The injector will inject null
for the myService
dependency instead of giving an error if the MyService
provider cannot be identified in the injector hierarchy.
The @Optional
decorator is useful when you want to specify that a dependency is not required for a component to function properly.
It can also be useful when you want to test a component in isolation and need to provide mock dependencies.
It’s important to remember that the
@Optional
decorator makes no changes to the injector’s behavior. The dependency will be injected normally if it is located in the injector hierarchy.
References and Links
Here are more related references and links that discuss the same subject:
- Angular Documentation
- Dependency injection tokens
- Dependency injection in Angular
- How to use Services in Angular ?
- How to use Providers in Angular ?
- Using Injector , @Injectable & @Inject in Angular
- How to create a singleton service in Angular ?
- Using provideIn root , any & platform in Angular ?
- How to use ViewProviders in Angular ?
- Using @Self , @SkipSelf & Optional Decorators in Angular
- How to use APP_INITIALIZER provider in Angular ?