Home Angular Tutorials Using @Self, @SkipSelf & Optional Decorators in Angular

Using @Self, @SkipSelf & Optional Decorators in Angular

by aouidane.med.amine
159,460 views 15 min read

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.

angular Injector hierachy

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

You may also like