Reputation: 859
I have a service AuthenticationService
that loads AngularFirestore
. The service is loaded in RootComponent
. All app modules are lazy-loaded in RootComponent
(it has the main router-outlet
). Now there are many sub-modules that also load AngularFirestore
.
I have to ensure that AuthenticationService
is initialized (async stuff) before the components and modules are loaded up, so I have put it in APP_INITIALIZER
provider. This causes cyclic-dependency Cannot instantiate cyclic dependency! AngularFirestore
.
If I don't put it in APP_INITIALIZER
it works but the app runs without AuthenticationService
being initialized.
Is there a way around this? (besides adding auth.initialize()
in all components)
App tree:
AppComponent -> RootComponent(AuthenticationService) -> All Submodules(AuthenticationService, AngularFirestore)
// constructor of AuthenticationService
constructor(
private auth : AngularFireAuth,
private remoteconfig : AngularFireRemoteConfig,
private keepalive: Keepalive,
private idle: Idle,
private toast : ToastService,
private router : Router,
private fs : AngularFirestore,
private http : HttpClient,
)
// providers in app.module.ts
{
provide: APP_INITIALIZER,
multi: true,
useFactory: authFactory,
deps: [
AuthenticationService
]
}
// Factory for APP_INITIALIZER
export function authFactory(
auth : AuthenticationService
) {
return () : Promise<any> => auth.initialize();
}
Regards!
Upvotes: 2
Views: 494
Reputation: 859
So after going through a plethora of github comments and unrelated SO questions I came up with a solution that I skimmed through for an unrelated issue in Github comments.
TLDR: Make injection by creating a new service for AngularFirestore
just for AuthenticationService
or for the whole app. I went with the latter.
Understanding the problem:
From what I understand, the issue is because my AuthenticationService
loads AngularFirestore
and makes it part of its dependency tree. Now any subsequent injection of AuthenticationService
and AngularFirestore
makes a cyclic dependency, because injecting AuthenticationService
makes AngularFirestore
part of the dependency tree, and when I inject AngularFirestore
after that it creates two injections of AngularFirestore
. Hence the error. I may be completely wrong, but I think this was the issue.
Solution:
Create a service for AngularFirestore
import. This, I think, moves it out of the dependency tree and injects it as a service making it OK for any subsequent injections of AngularFirestore
safe.
// appfirestoreservice.ts
import { Injectable } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
@Injectable({
providedIn: 'root'
})
export class AppFirestoreService {
public fs : AngularFirestore;
public readonly collection = this._fs.collection;
public readonly doc = this._fs.doc;
public readonly createId = this._fs.createId;
constructor(
private _fs : AngularFirestore,
) {
this.fs = _fs;
}
}
// App Initializer in AppModule
{
provide: APP_INITIALIZER,
multi: true,
useFactory: initFactory,
deps: [
AppServiceInitializerService,
RemoteConfigService,
AuthenticationService,
]
},
For my case I had to create a service just to load RemoteConfigService
and AuthenticationService
because they have to be initialized one after the other.
Regards!
Upvotes: 1