Search code examples
javascriptangularjsangular-promiseangularjs-serviceangular-http

Angular Service Not Filtering Data


I am fetching the details from an API using Angular Service and I want to return only the matching items. Meaning, after I type some text, I will click a button, which will call a function in a Controller which will call the Service to get the details.

Now my problem, is that it returns the entire list not the filtered list, I have stored filter result into an array I want to return that array(foundItems).

This is my code

(function() {
angular.module('NarrowItDownApp',[])
.constant('url',"https://davids-restaurant.herokuapp.com/menu_items.json")
.controller('NarrowItDownController',['$scope','MenuSearchService',function($scope,MenuSearchService) {
    var items=this;
    items.searchitem="";
    items.getitems=function() {
        MenuSearchService.getMatchedMenuItems(items.searchitem).then(function(response) {
            this.found=response.data;
            console.log(this.found);
        })
        .catch(function(response) {
            this.found=response.data;
            console.log(this.found);
        });
    };
}])
.service('MenuSearchService',['$http','url',function($http,url) {
    var service=this;
    service.getMatchedMenuItems=function(searchitem)
    {
        var foundItems=[];
        var key;
        return $http.get(url).success(function(data) {
            for(var i=0;i<data.menu_items.length;i++)
            {
                var temp=data.menu_items[i];
                //Old method
                /*for(key in temp)
                {
                    if(temp.hasOwnProperty(key))
                    {
                        console.log(temp[key])
                    }
                }*/
                Object.keys(temp).forEach(function(items)
                {
                    if(searchitem==temp[items])
                    {
                        foundItems.push(temp);
                    }
                });
            };
            console.log(foundItems);
            return foundItems;
        })
        .error(function(data) {
            console.log('error');
            return data;
        });
        return foundItems;
    };
}]);
})();

Solution

  • Now my problem, is that it returns the entire list not the filtered list, I have stored filter result into an array I want to return that array(foundItems).

    The reason that the service returns the entire list is that the .success and .error methods ignore return values. Use .then and .catch instead.

    service.getMatchedMenuItems=function(searchitem)
    {
        var foundItems=[];
        var key;
        //return $http.get(url).success(function(data) {
        //USE .then method
        return $http.get(url).then(function(response) {
            var data = response.data;
            for(var i=0;i<data.menu_items.length;i++)
            {
                var temp=data.menu_items[i];
                Object.keys(temp).forEach(function(items)
                {
                    if(searchitem==temp[items])
                    {
                        foundItems.push(temp);
                    }
                });
            };
            console.log(foundItems);
            return foundItems;
        })
        //.error(function(data) {
        //USE .catch method
        .catch(function(errorResponse) {
            console.log(errorResponse.status);
            //return data;
            //THROW to chain rejection
            throw errorResponse;
        });
        //return foundItems;
    };
    

    Also it is important to use a throw statement in the rejection handler. Otherwise the rejected promise will be converted to a successful promise.

    For more information, see Angular execution order with $q.