Services with ES6 (AngularJS)

11,551

You need to use this.$http inside your getResults method.

(() => {
  'use strict';
      
class ResultsFinder {
	
    static $inject = ['$http'];   
    constructor($http) {
        this.$http = $http;
    }
		
    getResults() {
        return this.$http.get('/foo/bar/');
    }
}

  /**
   * @ngdoc service
   * @name itemManager.service:ResultsFinder
   *
   * @description
   *
   */
  angular
    .module('itemManager')
    .service('ResultsFinder', ResultsFinder);
}());

As a side note, I added a static $inject "annotation" to your class. This is a best practice if you are not using something like ngAnnotate. It also makes it easier to change out implementations by only changing the $inject values.

If you are a ES5 developer it may help to think about how this would look in ES5

ResultsFinder.$inject = ['$http'];
var ResultsFinder = function($http) {
    this.$http = $http;
}

ResultsFinder.prototype.getResults = function() {
    return this.$http.get('/foo/bar/');
}

NOTE

Since you are using ES6, should probably use ES6 modules to organize your code.

You define and export your angular-module within an ES6 module:

import {module} from 'angular';

export var itemManager = module('itemManager', []);

Then import the Angular module

import {itemManager} from '../itemManager';

class ResultsFinder {

    static $inject = ['$http'];   
    constructor($http) {
        this.$http = $http;
    }

    getResults() {
        return this.$http.get('/foo/bar/');
    }
}

itemManager.service('ResultFinder', ResultFinder);
Share:
11,551

Related videos on Youtube

jeffarese
Author by

jeffarese

I develop smooth, high-performance webapps and I have fun doing it. React, Redux, Angular, TypeScript, Jest, Enzyme, Karma, Jasmine

Updated on June 04, 2022

Comments

  • jeffarese
    jeffarese almost 2 years

    I'm having problems accessing Angular built-in services such as $http when creating a service with ES6.

    For example, I'm creating a "ResultsFinder" service that will do an AJAX call and then do some stuff. The problem is that I only have access to $http on the constructor (if I pass it as an argument), but not on other methods (such as getResults).

    See this code example:

    (() => {
      'use strict';
    
      class ResultsFinder {
        constructor($http) {}
        getResults() {
          return 'ResultsFinder';
        }
      }
    
      /**
       * @ngdoc service
       * @name itemManager.service:ResultsFinder
       *
       * @description
       *
       */
      angular
        .module('itemManager')
        .service('ResultsFinder', ResultsFinder);
    }());

    Inside getResults I don't have access to $http. In order to have access I should do something that I don't feel right like this:

    (() => {
      'use strict';
    
      class ResultsFinder {
        constructor($http) {
          this.$http = $http;
        }
        getResults() {
          // Here I have access to this.$http
          return 'ResultsFinder';
        }
      }
    
      /**
       * @ngdoc service
       * @name itemManager.service:ResultsFinder
       *
       * @description
       *
       */
      angular
        .module('itemManager')
        .service('ResultsFinder', ResultsFinder);
    }());

    Anyone can give me some advice about the proper way to handle this?

  • Martin
    Martin about 9 years
    When your code is uglified or minified the function parameter $http will be replaces with something like: a. Angular will not know what service to inject at this point. That is where $inject comes in. This is typically only an issue that is seen once code is shipped to QA or PROD.
  • Martin
    Martin about 9 years
    You should use $http rather than http.
  • Martin
    Martin about 9 years
    Yes, in your controller you would want MyController.$inject = ['ResultsFinder'];.
  • Jordan Carroll
    Jordan Carroll about 8 years
    This answer doesn't seem like good practice, to me. I agree with the OP's hesitation to use this.$http because then that just becomes cruft outside of the service. Someone could then use ResultsFinder.$http - I agree, this doesn't feel right. Any other solutions?
  • Martin
    Martin about 8 years
    Jordan -- You would only be able to do ResultsFinder.$http if during build you DON'T wrap your module in an IIFE. This should always be done. Or, just wrap the class in a IIFE. Doing encapsulation within the constructor will give you a performance hit.