Issue
EDIT: This has now been fixed thanks to the accepted answer, the stackblitz now contains working code
First of all I know its not recommended to create module scoped services, I just want to know if it is possible to do.
I have created a module, service and component. The code is below.
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Fm5Component } from './fm5/fm5.component';
@NgModule({
declarations: [
Fm5Component
],
imports: [
CommonModule
]
})
export class FeatureModule5Module { }
import { Component, OnInit } from '@angular/core';
import { Fm5Service } from '../fm5.service';
@Component({
selector: 'app-fm5',
templateUrl: './fm5.component.html',
styleUrls: ['./fm5.component.scss']
})
export class Fm5Component implements OnInit {
constructor(private fm5Service: Fm5Service) { }
ngOnInit(): void {
this.fm5Service.saySomething();
}
}
import { Injectable } from '@angular/core';
import { FeatureModule5Module } from './feature-module5.module';
@Injectable({
providedIn: FeatureModule5Module
})
export class Fm5Service {
constructor() { }
saySomething(){
console.log("something");
}
}
However when I try to run this I get a circular dependency error. Is it possible to fix this somehow?
I see that this question comes up quite a bit on here in various forms but I'm still none the wiser as to if it can be done.
I've created a stackblitz replicating the error: https://stackblitz.com/edit/angular-ivy-tyavuk?file=src/app/feature-module5/fm5/fm5.service.ts
Solution
Its a known issue with Angular/Typescript. Check out this thread: https://github.com/angular/angular-cli/issues/10170#issuecomment-415758304
Generally, you should use
providedInproperty to limit it to a non-root module, when you are creating a thrid-party library. Because this feature was introduced for allowing tree shakeable services.
- In an application, you will write a service only if you intend to consume it. But in a library, a consumer may or may not consume it. Therefore, it requires tree-shaking.
This is the Circular Dependency that is currently created:
service--[provides itself to]-->module--[declares]-->component--[depends on]-->service.
This prevents the bundler from tree-shaking it. Therefore Angular warns you about using this pattern with a Circular Dependency error.
Understanding providers scope & providedIn: XYZModule.
When you specify scope of a service(
XYZService) withprovidedInto a particular module, you are telling Angular -> Hey Angular, please limit this service instance to the specified module.Case 1: The
XYZModuleis imported by another module(s). In this case, the single instance ofXYZServicewill be shared in that module. So, any component in that module can injectXYZServicewithout any circular dependency error.Case 2: The
XYZModuleis imported byAppModule, In this case, your service instance will be shared throughout the application. Even with any lazy loaded module.Case 3: The
XYZModuleis imported byAppModule&Module2individually. In this case,Module2will create its own instance ofXYZService. All components declared insideModule2will not shareAppModule's instance ofXYZService
I have created the scenario in this stackblitz
Use the providers array in the @NgModule to limit the scope of a service to that module when creating an application.
@NgModule({
declarations: [
Fm5Component
],
imports: [
CommonModule
],
providers:[Fm5Service]
})
export class FeatureModule5Module { }
Still, if you want to use providedIn syntax, check this visual to understand the problem & its solution using a new Module: https://github.com/angular/angular-cli/issues/10170#issuecomment-414270051
Answered By - Pankaj Sati

0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.