45

I have an Angular service/provider that serves json data to my controller which works great:

    angular.module('myApp.services', ['ngResource']).
      factory("statesProvider", function($resource){
      return $resource('../data/states.json', {}, {
        query: {method: 'GET', params: {}, isArray: false}
      });
    });

But I also need to serve json data to the same controller from another file counties.json.

Where can I find out how to I write a service that serves both files to my controller?

Dmitry Evseev
  • 11,313
  • 3
  • 31
  • 47
Henry Zhu
  • 3,443
  • 5
  • 24
  • 36

2 Answers2

95

You can update service to return a hash of resources, not a single one:

angular.module('myApp.services', ['ngResource']).
  factory("geoProvider", function($resource) {
    return {
      states: $resource('../data/states.json', {}, {
        query: { method: 'GET', params: {}, isArray: false }
      }),
      countries: $resource('../data/countries.json', {}, {
        query: { method: 'GET', params: {}, isArray: false }
      })
    };
  });

You will be able to use it adding .query() at the end your function name i.e. geoProvider.states.query() and geoProvider.countries.query() and myApp.services has to be injected into your controller, then inject geoProvider service into controller itself as well.

Dmitry Evseev
  • 11,313
  • 3
  • 31
  • 47
  • 1
    This looks like what I am searching for but can you explain how to call "states" and "countries" from the controller? Normally, I would just do myApp.services.query(). Thanks – chapstick Oct 11 '13 at 17:19
  • 2
    @chapstick In order to use it you should inject `myApp.services` module into module that contains controller, then inject `geoProvider` service into controller itself. After you'll be able to use `geoProvider.states.query()` and `geoProvider.countries.query()` in the controller – Dmitry Evseev Oct 12 '13 at 07:10
9

I'm assuming you want to execute some code when both files have loaded. Promises work really well for this. I don't think resources return promises, but you can use the $http service for simple ajax calls.

Here I define one service each for the two data files, and a third service that returns a promise that gets fulfilled when both files are done loading.

factory('states',function($http) {
    return $http.get('../data/states.json');
}).
factory('countries',function($http) {
    return $http.get('../data/countries.json');
}).
factory('statesAndCountries', function($q, states, countries) {
    return $q.all([states, countries]);
});

Then in your controller:

statesAndCountries.then(function(data) {
    var stateData = data[0];
    var countryData = data[1];
    // do stuff with stateData and countryData here
});
Karen Zilles
  • 7,613
  • 3
  • 32
  • 31