1

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.

4 Answers 4

6

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;
    }
});
Sign up to request clarification or add additional context in comments.

4 Comments

Thats what I am doing in the success method by calling an anonymous function.
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.
It says "$q is not defined". Am I missing something?
Thanks it worked. BTW, do you have any idea why my returned JSON list objects coming under "data.$values" instead of directly "data" object.
6

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
            });        
    }   
});

3 Comments

It says "$q is not defined". Am I missing something?
Sorry, missed it in the service dependencies.
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
1

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.

Comments

0

I use this for communication between Angular Web Data Service and Web Api Controller.

.factory('lookUpLedgerListByGLCode', function ($resource) {
    return $resource(webApiBaseUrl + 'getILedgerListByGLCode', {}, {
        query: { method: 'GET', isArray: true }
    });
})

OR

.factory('bankList', function ($resource) {
    return $resource(webApiBaseUrl + 'getBanklist_p', {}, {
        post: {
            method: 'POST', isArray: false,
            headers: { 'Content-Type': 'application/json' }
        }
    });
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.