Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert an angular $resource factory (not service) to ES6

I'd like to start preparing for Angular 2 by converting existing code over to ES6 (as recommended in this video).

However, I'm immediately stumped, or perhaps unsure about how to proceed. In the video they show a conversion of a service. In my code I'm trying to convert a factory, which is similar but actually quite different when trying to convert to ES6. The service easily follows the class instantiation method, but factories need to return the injected object.

My code started like this:

melange.factory('SomeService', ['$resource', function ($resource) {
  var someResource = $resource('/api/endpoint');

  someResource.customQuery = function() {
    // ... do some custom stuff
  };

  return someResource;
}]);

My First Failed Attempt - So I immediately started to convert over to ES6 and came up with this:

// notice I changed this to service instead of factory
melange.service('SomeService', ['$resource', SomeService]);

class SomeService {
  constructor ($resource) {
    var someResource = $resource('/api/endpoint');

    someResource.customQuery = function() {
      // ... do some custom stuff
    };

    return someResource;
  }
}

But that's not right... the constructor is returning a resource.


Maybe Success Attempt - So it's really the Resource (or really a Route object) that is the thing I want to 'class-ify'. But since a Resource object has a specific interface already of methods, I'll need my class to extend the base Resource object. But that is generated dynamically by calling the $resource factory function. So I came up with this maybe correct code:

melange.service('SomeService', ['$resource', SomeResource]);
var $resource = angular.injector().get('$resource');

class SomeResource extend $resource('/api/endpoint') {
  customQuery() {
    // ... do some custom stuff
  }
}

So I have to get $resource from the injector before declaring my class. I'm just not sure if extending $resource('/api/endpoint') is even valid ES6. It seems to work generally during babel transpile though.


Am I doing this right?

like image 512
Tim Kindberg Avatar asked Mar 11 '15 16:03

Tim Kindberg


1 Answers

You can't use ES6 classes as easily with factories, so I would advise making everything a service.

angular.module('test', [])
.service('SomeService', ['$resource', class SomeService {
  constructor($resource) {
    this.resource = $resource('/api/something');
  }
  customQuery() {
    return doSomething(this.resource);
  }
}]);

Here's how it looks when it's transpiled: http://goo.gl/8Q4c8b

Here's a working plunkr with the transpiled code inside: http://plnkr.co/edit/RS48OerLYQCERPYzbuuM?p=preview

like image 169
Andrew Joslin Avatar answered Oct 11 '22 09:10

Andrew Joslin