The problem
For the past week I've been working on a authentication library for an Angular2 project. This library is mostly service based and should work almost directly out of the box. The only thing you need to do is include it in your app and set the config object for it.
The main service here is the AuthService. This service includes both the Http and another custom service. The thing is that both these dependencies require the developer to point out the providers for these classes. I'm not sure If I've got this right, but I've seen solutions where they need to import HTTP_PROVIDERS in order to use Http.
So if I import the AuthService as a dependency, I still need to import both the HTTP_PROVIDERS and custom service to make the DI work.
bootstrap(App, [AuthService, HTTP_PROVIDERS, CustomService]);
This messes up my idea of the module being easy to include. I'd like to only supply the import AuthService.
Thing I tried so far
First of all I started out reading some of the blogs about DI in Angular2. As most of you may know Thoughtram is doing a great job on supplying this information (also EggHead.io). I ended up reading these two posts:
http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html http://blog.thoughtram.io/angular/2015/09/17/resolve-service-dependencies-in-angular-2.html
After reading them I thought the solution was simple, but after a while this seemed not the case. I guess I'm missing the point here. Also working Spring boot where DI is the main selling point, it seemed odd that I did not manage to get it working (might be the fact that Angular2 is still in Alpha and documentation is scarce).
Solutions I tried
So I tried some solution I came up with, but none of them worked.
Providing a constant
My first thought was to look at the HTTP_PROVIDERS constant that was like a provider for the Http dependency. I ended up looking at the source code for it.
After that I thought that I'd best try to implement this for my own class.
export const AUTH_PROVIDERS: any[] = [
provide(AuthService, {
useFactory: (http, customService) => new AuthService(http, customService),
deps: [Http, CustomService]
})
,
provide(CustomService, {
useFactory: () => new CustomService(),
})
];
Once completed I included it in my bootstrap function, after which I was greeted with another error.
Token must be defined!
I took some time trying to find the problem, but I did not manage to do so.
Using an annotation
One of the new things in Angular2 is annotations. So I hoped one of these would be able to help me out with my problem. The @Component and @View seemed not the ones I needed. I believe they focus more on visual aspects of an object that functional (as the View is not something I need, but is mandatory).
The next part can seem odd as I could not find if this was an annotation or not (probably not...). I tried giving @Provider a shot. That resulted in the following "possible" solution.
@Provider({
token: 'AuthService',
useFactory: (http, customService) => new AuthService(http, customService)
...
})
export class AuthService{
constructor(http: Http, customService, CustomService){...}
}
This just gave me another error, but this time it was thrown by the Typescript compiler.
error TS2348: Value of type 'typeof Provider' is not callable. Did you mean to include 'new'?
Anyways can someone please help me with this. Is one of the solutions above a step in the right direction or am I doing something horribly wrong?
Thanks in advance.