I still make an initClass() method that describes the constructor parameters that need to be injected, but note that the factory method only injects an $injector that it uses to create the service. As with anything, there are many different ways you can do this. At the end I'll show you a more brief way to do this.
import 'angular'; /*
* Angular service as a class */ export class DataService {
static initClass() { DataService .$inject = ['$resource', '$q']; } constructor($resource, $q) { this.$resoure = $resource; this.$q = $q; this.latest = $resource('/data/latest/:name'); this.tables = $resource('/data/config/default_table'); this.tags = $resource('/data/tags', {}, {get: {method: 'GET', isArray: true}}); } getLatestValue(key) { var deferred = this.$q.defer(); this.latest.get({"name": key}).$promise.then( (result) => { deferred.resolve(angular.fromJson(angular.toJson(result))); }, (error) => { deferred.reject(error); }); return deferred.promise; } getTableConfig() { var deferred = this.$q.defer(); this.tables.get().$promise.then((result) => { deferred.resolve(angular.fromJson(angular.toJson(result))); }, (error) => { deferred.reject(error); }); return deferred.promise; } getAllTags() { var defer = this.$q.defer(); /* This is an example of how to cache the result */ if (angular.isDefined(this.tag_cache)) { /* Resolve from the cache */ defer.resolve(tag_cache); } else { /* Not cached, so resolve from the backend server */ tags.get().$promise.then( (allTags) => { this.tag_cache = {}; alltags = angular.fromJson(angular.toJson(allTags)); angular.forEach(allTags, function (t) { tag_cache[t.name] = t; }); defer.resolve(tag_cache); }, (error) => { defer.reject(error); }); } return defer.promise; } static register(module) { module.factory('dataservice', [ '$injector', function($injector) { return $injector.instantiate(DataService); }]); } }
If you're not like me (and you don't care about having the injectables defined in the source close to the constructor) you can skip initClass() and setting up DataService.$inject and just set them when you call instantiate():
static register(module) { module.factory('dataservice', [ '$injector', function($injector) { return $injector.instantiate(DataService, [ '$q', '$resource' ] ); }]); }
Back in app.js you do just as before:
import { DataService } from 'services/dataservice'; ... DataService.register(mainModule); ...
I'm doing all of this with System.js but it's on my short list to try it all with webpack. I will let you know when that works.
By the way .. if you're wondering what all this fromJson(toJson()) stuff is: the object that comes back from $resource has some extra items in it (beyond what the server returns). That's the recommend trick for stripping them out. It's not really necessary to strip them out - in particular, if you use ngResource to POST them back it strips things like $promise out before POSTing. Again, though, I'm a little OCD about this, especially if I display the raw result using the angular json $filter, so I take the trouble to clean up the object. It's an optional step.