@mhartington
I had an issue handling many services
and solved it before finish this thread, but Iāll share it anyways
I have a heavy Page where I offer my main service,
so I decoupled it and now I have with six providers for it.
One of my services werenāt resolving all its parameters,
and I wenāt crazy trying to figure out what was the cause.
Basically I have:
I have a thin Page now moving away mostly of the code to the services and I feel Iām able to maintain everything easily.
Basically all of them depends on the Event Bus which communicates them, and the MainService takes the DataService too to perform some business logic changes, and finally the Page takes the Event, Data and Main Services.
I had the problem on the MainService not being able to resolve the DataService, and I had to go deep into Reflect.js to see where the things went wild. Finally, now Iām aware that the declaration order in which Angular 2 loads the @Injectables is important.
Iām using a Barrel, and there the DataService was exported AFTER the MainService, that was the LESSON of the day. Iāll be aware to put the dependencies before on my barrels now
I hope that this will be useful for someone one day
Iām not sure what a Barrel is, but if itās some sort of bundler, I think your problem is with it. Angularās DI should not be tripped up by ordering of declarations, with the caveat that all classes should be declared in separate compilation units, lest you bang into this issue.
but they doesnāt warn about dependency issues loading the metadata of the classes
if you donāt have enough care about the order inside the barrel,
now I understand why Angularās barrels are not alpabetically sorted
Iāve organized those services on a separated folder app/services with a barrel (index.ts) that looks like:
// sorted taking in account dependencies
export * from './events.service';
export * from './socket.service';
export * from './system.service';
export * from './data.service';
export * from './gui.handler';
When the classes are being processed and this barrel is āparsedā, I found that Reflect.js isnāt called to decorate the dependency with its @Injectable, maybe an issue with Angularās Injector, I donāt have enough idea, but I think they know the order is important there, just have to add a big warning when using barrels.
@Injectable()
export class DataService {
constructor(private _ebus:EventsBus) {
}
}
@Injectable()
export class EventsBus {
}
@Injectable()
export class GuiHandlerService {
}
// these are deliberately inverted from how you listed them
export * from './gui.handler';
export * from './events.service';
export * from './data.service';
export * from './system.service';
export * from './socket.service';
@Injectable()
export class SocketService {
constructor(private _ebus:EventsBus) {
}
}
@Injectable()
export class SystemService {
constructor(private _ebus:EventsBus) {
}
}
Constructor for page class (which imports all these from the barrel):
My english is so bad
Inject DataService to GuiHandlerService and it wonāt work because the ābarrel havenāt decoratedā DataService when processing GuiHandlerService.
Uhm weird, I donāt know whatās different here then, I just know I reordered the barrel and it finally worked.
I had to console.log stuff inside Angular (god bless ionic serve) and finally got some tips on Reflect.js, which made me understand the parsing on browser-pack's _prelude.js was processing the services on the barrel, but Reflect wasnāt decorating the DataService nor the SystemService for unknown reasons.
Maybe itās my App size and complexity that starts to be messy, thatās why Iām reworking
I think I see the issue:
You havenāt injected GuiHandlerService in your Page, so it wonāt be created and the problem wonāt appear! I just added all the services to my Page in order to be created after my Event Bus and realised this.
I think weāre going to need some kind of complete plunkr or github project to really diagnose this properly. Iām pretty confident that something outside of export ordering is going on.
Any chance of getting help with a circular reference between providerA and providerB ? They both reference each other but I end up with an error: Can't resolve all parameters for...
@Injectable()
export class ProviderA {
constructor(public providerB:ProviderB) { }
}
@Injectable()
export class ProviderB {
constructor(public providerA:ProviderA) { }
}