Search code examples
typescriptangularsystemjs

Angular2, manually resolve a type by string/name


Is it possible to manually resolve a component by only knowing it's name?

I have a string variable which will contain the name of a component, lets say "UserService"

I need to be able to resolve this type, I've looked at Injctor, I can see from the documenation there is a resolve() and resolveAndCreate() (https://angular.io/docs/ts/latest/api/core/Injector-class.html)

but I don't have the Type.

Thanks

Steve

EDIT: tried the following:

System.import("path/to/service").then(p=>{

     var injector = Injector.resolveAndCreate([p[this.serviceName]]);//works

     var serviceInstance = injector.get(p[this.serviceName]); //Fails with "No provider for Http! (UserService -> Http)".


});

I have Http available, it's been provided during bootstrap and this works fine for other parts of the application.

bootstrap(AppComponent, [
    ROUTER_PROVIDERS, Http, HTTP_PROVIDERS, UrlBuilderService,
    provide(LocationStrategy, { useClass: HashLocationStrategy }),
    provide('notification', { useClass: NotificationService })
]);

Any idea's?

Further Edit:

I now call the resolveAndCreate like this:

var injector = Injector.resolveAndCreate([p[this.serviceName], Http]);

which failed with

No provider for ConnectionBackend! (UserService -> Http -> ConnectionBackend)

So i called it like this:

var injector = Injector.resolveAndCreate([p[this.serviceName], Http, ConnectionBackend]);

which failed with some other missing stuff.

Changed to this

var injector = Injector.resolveAndCreate([p[this.serviceName], HTTP_PROVIDERS]);

and now all is working.

What I do not understand is why it's not automatically resolving these components because i have them provided during bootstrap.


Solution

  • You can achieve this by using system.js (that is loader used by angular2) by doing so:

    System.import('path/to/UserService').then(m => 
    {
        //Here you can access user service and use it in injector etc.
        Injector.resolveAndCreate([m.UserService]);
    });
    

    This technique is well illustrated in this article: Lazy Loading of Route Components in Angular 2