5

I have an Angular1 service with name, say, 'myService'

I then upgraded it using the Angular2 UpgradeAdapter like this:

var upgradeAdapter = new ng.upgrade.UpgradeAdapter();
upgradeAdapter.upgradeNg1Provider('myService');

Now I need to inject it to the angular2 component. Official upgrade guide only has typescript version for now. In typescript you use @Inject anotation with the service name for it like so:

export class MyComponent {
  constructor(@Inject('myService') service:MyService) {
    ...
  }
} 

What is the syntax for injecting a service by name using ES5?

Dmitry Klochkov
  • 2,484
  • 24
  • 31

2 Answers2

5

To complete the pixelbits' answer, you need also define my service within the providers list either:

  • At the application level

    document.addEventListener('DOMContentLoaded', function() {
      ng.platform.browser.bootstrap(Cmp, [MyService]);
    });
    
  • At the component level

    var Cmp = ng.core.
     Component({
       selector: 'cmp',
       providers: [ MyService ]
     }).
     (...)
     Class({
       constructor: [MyService, function(service) {
       }]
     });
    

It depends on what you want to do: share your service instance for all elements in the Angular2 application or per component.

This answers could give more details on dependency injection in Angular2 with ES5: Dependency Injection in Angular 2 with ES5.

Edit

In fact, there is a subtlety. IN the case of upgrade you need not to bootstrap using the ng.platform.browser.bootstrap function but the one from the upgrade object.

upgrade.bootstrap(document.body, ['heroApp']);

Where heroApp is the Angular1 module containing services and factories I want to use in the Angular2 application.

In fact, when you call the upgradeNg1Provider method on the upgrade, corresponding providers are registered within its associated injector. This means that you don't need to specify them at described above.

So you simply need to do that where you want to inject:

(...)
Class({
  constructor: [ ng.core.Inject('customService'),
                 ng.core.Inject('customFactory'),
                 function(cService, cFactory) {
  }]
});

Miško Hevery provides a great plunkr for this: http://plnkr.co/edit/yMjghOFhFWuY8G1fVIEg?p=preview.

Hope it helps you, Thierry

Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • Thanks for your answer. It looks like injection by type. But I don't actualy have the MyService class/function.The service is declared like this: myModule.factory('myService', [function () {...}]). Or this class/function is somehow created during the upgrade? – Dmitry Klochkov Jan 20 '16 at 13:44
  • I can't make work with Angular1 factories. I expect to have something like that: `constructor: [ new ng.core.Inject('customFactory'), function(cFactory) { (...) }]`. But I have the following error: `No provider for customFactory! (class1 -> customFactory)`. In fact, I don't know what to put within the providers list (application or component level). I made some tries with the `ng.core.provide` function without success... – Thierry Templier Jan 20 '16 at 16:41
  • I created an issue in Github for this: https://github.com/angular/angular/issues/6588. – Thierry Templier Jan 20 '16 at 16:53
  • Miško Hevery answered the issue ;-) I updated my answer with a working solution... – Thierry Templier Jan 21 '16 at 06:40
2

Use the array notation for constructor DI of services:

.Class({
    constructor: [MyService, function (service) {
      ...
 }],
Michael Kang
  • 52,003
  • 16
  • 103
  • 135