Sign up ×
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them, it only takes a minute:

I am new to AngularJS & working on a sample. In my sample app I have an MVC Web api (which returns some data from db) & it will be called from the Angular Services and returns the data to the Controller. The issue is I am getting the data in my Services success method properly but in my controller it always shows undefined & nothing is displayed in the view. Please see the code below:

My Controller code:

app.controller('CustomerController', function ($scope, customerService) {    
    //Perform the initialization
    init();

    function init() {
        $scope.customers= customerService.getCustomers();        
    }   
});

My Services code:

app.service('customerService', function ($http){
       this.getCustomers = function () {
        $http({
            method: 'GET',
            url: 'api/customer'           
        }).
    success(function (data, status, headers, config) {
        return data;
    }).
    error(function (data, status) {
        console.log("Request Failed");
    });

    }
});

Please help me to fix this issue.

share|improve this question

3 Answers 3

up vote 6 down vote accepted

That's because your service defines the function getCustomers but the method itself doesn't actually return anything, it just makes an http call.

You need to provide a callback function in the form of something like

$http.get('/api/customer').success(successCallback);

and then have the callback return or set the data to your controller. To do it that way the callback would probably have to come from the controller itself, though.

or better yet, you could use a promise to handle the return when it comes back.

The promise could look something like

app.service('customerService', function ($http, $q){
   this.getCustomers = function () {
       var deferred = $q.defer();
       $http({
           method: 'GET',
           url: 'api/customer'           
        }).
        success(function (data, status, headers, config) {
            deferred.resolve(data)
        }).
        error(function (data, status) {
            deferred.reject(data);
        });

        return deferred;
    }
});
share|improve this answer
    
Thats what I am doing in the success method by calling an anonymous function. – user972255 Oct 14 '13 at 22:28
    
no what I meant by the callback was you could have the controller pass the callback into the service and get the data that way. But I think the promise is the better way to go anyway. – Joseph Oct 14 '13 at 22:30
    
It says "$q is not defined". Am I missing something? – user972255 Oct 14 '13 at 22:40
    
you have to inject it, I'll update – Joseph Oct 14 '13 at 23:57
    
Thanks it worked. BTW, do you have any idea why my returned JSON list objects coming under "data.$values" instead of directly "data" object. – user972255 Oct 15 '13 at 2:30

Your problem is in your service implementation. You cannot simply return data since that is in the asynchronous success callback.

Instead you might return a promise and then handle that in your controller:

app.service('customerService', function ($http, $q){
    this.getCustomers = function () {
        var deferred = $q.defer();
        $http({
            method: 'GET',
            url: 'api/customer'           
        })
        .success(function (data, status, headers, config) {
           // any required additional processing here
           q.resolve(data);
        })
        .error(function (data, status) {
           q.reject(data);
        });
        return deferred.promise;
    }
});

Of course if you don't require the additional processing, you can also just return the result of the $http call (which is also a promise).

Then in your controller:

app.controller('CustomerController', function ($scope, customerService) {    
    //Perform the initialization
    init();

    function init() {
        customerService.getCustomers()
            .then(function(data) {
               $scope.customers= data;
            }, function(error) {
               // error handling here
            });        
    }   
});
share|improve this answer
    
It says "$q is not defined". Am I missing something? – user972255 Oct 14 '13 at 22:40
    
Sorry, missed it in the service dependencies. – ksimons Oct 14 '13 at 22:48
    
Thanks it worked. – user972255 Oct 15 '13 at 2:03
    
I've got error trying to resolve. by changing this: q.resolve(data); => deferred.resolve(data); and q.reject(data); => deferred.reject(data); it worked – eflles Jan 10 at 8:47

VERY late answer, but, Angular's $http methods return promises, so there's no need for wrapping everything into promise form with $q. So, you can just:

app.service('CustomerService', function ($http) {
  this.getCustomers = function () {
    return $http.get('/api/customer');
  };
});

and then call the .success() or .error() shortcut methods in your client controller.

If you want to take it a step further and have a fully-fledged RESTful CustomerService without having to write this boilerplate, I'd recommend the restangular library, which makes all sorts of methods available to you - assuming of course your backend responds to HTTP verbs in the "standard fashion".

Then you could just do this:

app.service('CustomerService', function (Restangular) {
  return Restangular.service('api/customer');
});

and call the methods Restangular makes available to you.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.