Luxalpa
Luxalpa

Reputation: 430

Inject HTTP service into asynchronously created service?

I have the following problem:

Since my page is pretty huge, I want to load the Services only on demand, i.e. when someone gets to a certain URL, I have an async route that then loads creates my view component(s) and services on demand. It works with the components, but the Dependency Injection gives me a problem:

If I just inject my newly created service into the components, then it creates multiple instances of the service (one for each component). This is because I can not put all the components as a child of the parent component and just do providers:[myService] there, but instead I have to do it for each independent component.

My "solution" to that problem was to not use NG2 dependency injection, and instead do my own simple:

let LayoutServiceClass = ng.core
    .Class({
        constructor: [ng.http.Http, function(http) {

        }]
    });

let LayoutService = new LayoutServiceClass();

Now, while this kinda works, it comes with the problem that I don't have DI in the service, i.e. the Http above doesn't get injected. Manually injecting it as well ( new ng.http.Http() ) turned out to be way too complicated and unsafe since I have to manually inject those dependencies and the dependencies' dependencies as well.

On the other hand, I tried using a custom injector for that service (somewhat according to https://angular.io/docs/js/latest/api/http/Http-class.html):

let injector = ng.core.Injector.resolveAndCreate([
    ng.http.HTTP_PROVIDERS,
    ng.http.Http
]);

this.http = injector.get(ng.http.Http);

but it failed with EXCEPTION: Tried to get instruction before the type was loaded.

Edit: using the injector.get in a timeout, i.e.

window.setTimeout(() => {
    this.http = injector.get(ng.http.Http);
});

solves that error but still comes up with Error: No provider for ConnectionBackend! (Http -> ConnectionBackend)

How do I do this properly?

Upvotes: 3

Views: 179

Answers (1)

Luxalpa
Luxalpa

Reputation: 430

ok looks like I solved it using:

let injector = ng.core.Injector.resolveAndCreate([
    ng.http.HTTP_PROVIDERS,
    ng.core.provide(ng.http.ConnectionBackend, {useClass: ng.http.XHRBackend}),
    ng.http.Http,
    LayoutServiceClass,
]);

let LayoutService = injector.get(LayoutServiceClass);

I'm still open to better solutions than this!

Upvotes: 0

Related Questions