Angular is an opiniated framework. It’s really an excitement to see how its diverging towards developer flexibility and becoming stronger day by day. I believe it’s a happy era for the Angular lovers.
Dependency injection and RxJS — In my opinion, are powerful features which made Angular unique and flexible. RxJS custom operators are a great way to compose complex logic into reusable functions.
Recently I came across a usecase where I need to create a custom RxJS operator which uses service to achieve some complex usecase.
You can use inject method to access desired service instance, inject must be used within dependency injection context though. To achieve this, Rxjs operator can be registered as a InjectionToken which uses useFactory function to instantiate its value. Since useFactory is a injection context, the services can be injected without any problem using the inject method.
Let’s see how the below service can be injected in a rxjs custom operator.
// Service @Injectable({ providedIn: 'root', }) export class Multiplier { public transfrom(val: number) { return val * 2; } }
The below custom RxJS operator simply multiple the given value with 2 using the Multiplier service.
import { inject, InjectionToken } from '@angular/core'; import { Multiplier } from '../services/multiplier'; import { map, OperatorFunction, pipe } from 'rxjs'; export const MULTIPLIER_OPERATOR: InjectionToken<OperatorFunction<number, number>> = new InjectionToken('Multipler operator', { factory(): OperatorFunction<number, number> { const multipler = inject(Multiplier); // injected Multipler service return pipe(map((x: number) => multipler.transfrom(x))); }, });
Now the custom operator can be used within the components using the @Inject decorator.
import { Component, Inject } from '@angular/core'; import { BehaviorSubject, Observable, of, OperatorFunction } from 'rxjs'; import { MULTIPLIER_OPERATOR } from './rxjs-operators/custom'; import { CommonModule } from '@angular/common'; export class App { private _count = 1; public base = new BehaviorSubject(this._count); public val = new Observable(); constructor( @Inject(MULTIPLIER_OPERATOR) // injected custom operator private multiplier: OperatorFunction<number, number>) { this.val = this.base.pipe(this.multiplier); // used rxjs operator } ..... }
There are several other ways to achieve this same usecase like creating a separate service and a method that would return custom operator. But I like InjectionToken approach due to its self containability. RxJS isn’t going anywhere in near future even with introduction of signals so it’s worth experimiting on it.
You can see the full working example here.
Happy Coding…?
The above is the detailed content of Angular Dependency Injection — Inject service inside custom Rxjs operators. For more information, please follow other related articles on the PHP Chinese website!