1

I'm developing a small AngularJS app and I'm currently struggling with creating a service.

I have a service that serves as a backend for providing contacts (name, address...). Until now they were hard-coded as an array in the service (instance.contacts=[...]), but now I'm trying to read them from a json file :

myModule.factory('contactService', ['$http',function ($http) {
    var instance = {};

    $http.get('contacts.json').success(function (data) {
        instance.contacts = data;
    });

    return instance;
}]);

I see in my browser console that the file has been read successfully, but I don't see any change on-screen.

So I tried the following instead, and it worked :

myModule.factory('contactService', ['$http',function ($http) {
    var instance = {
        contacts:[]
    };

    $http.get('contacts.json').success(function (data) {
        angular.forEach(data, function(item) {
            instance.contacts.push(item);
        });
    });

    return instance;
}]);

I don't know why the second code snippet works, and not the first. Could someone please help me understand ?

Olivier Croisier
  • 6,139
  • 25
  • 34

3 Answers3

4

$http is asynchronous, so you can't return an array because when you return it, it probably doesn't have any data in it yet. You actually have to return the promise:

var instance = $http('contacts.json');

return instance;

And then in your controller (or in another service):

contactService.then(function(response) {
  $scope.contacts = response.data;
});

Just remember that no matter where you access your service, you must interact with it as a promise using then.

Josh David Miller
  • 120,525
  • 16
  • 127
  • 95
0

You might be better off using ngResource, in which case your code should look something like this:

myModule.factory('contactService', function ($resource) {
    return $resource('contacts.json', {}, {
        get: {method: 'GET', isArray: true}
    });
})

Ensure that myModule has ngResource in its list of dependencies. Then within your controller you can access the data with contactService.get()

  • I recommend against using `ngResource` if the server-side API isn't restful - it can cause a lot of headaches. But if it is, it's great! – Josh David Miller Mar 01 '13 at 18:13
  • True, I just assume that everything is RESTful nowadays! –  Mar 01 '13 at 18:14
  • I cannot return a $resource directly, because my service has other methods (saveContact(), getContactById(), etc.). My goal is to pre-load a dataset in an array, nothing more - I don't have a restful server (yet). – Olivier Croisier Mar 01 '13 at 18:21
0

Just to give a full example, here is the plunker http://plnkr.co/edit/VsuAKNavPbHL7RWbrvKD?p=preview. The idea followed is just the same as metioned by Josh David Miller.

Rajkamal Subramanian
  • 6,884
  • 4
  • 52
  • 69