mlab37 mlab37 - 2 months ago 10
AngularJS Question

Trouble converting a simple function to a Factory or Service using Angular JS

I've searched SO and the web for a long time but still can't find the right answer to my problem. Although there are a lot of threads addressing function to Factory/Service conversion, none seem to apply to my current situation. I frequently use Services for setters/getters and $http calls without issue so I'm struggling to find out why I'm having so much trouble converting this simple function to a Factory or Service.

I have a table of data that I am paginating using the following code in my HTML:

<tr data-ng-repeat="book in filtered = (books | filter: query) | startFrom:currentPage*pageSize | limitTo:pageSize">


I'm then using a simple function to show the "Next" button when the table contains more than one page and to hide it if there is only one page or the user has reached the last page. I do so using
ng-show="showNext(filtered)"
. The function looks like this:

$scope.showNext = function(filtered){

var numPages = Math.ceil($scope.data.length/$scope.pageSize),
lastPage = $scope.currentPage+1;

if(filtered.length > $scope.pageSize && lastPage < numPages){
return true;
}else if(filtered.length > $scope.pageSize && lastPage === numPages){
return false;
}else{
return false;
}
};


This function works great in the Controller by itself, however, I would now like to use it across multiple controllers. My first attempt was to use a factory so I wrote this:

app.factory('PaginationService', function(){

var pagination = {};

pagination.showNext = function(data, pageSize, currentPage, filtered){
var numPages = Math.ceil(data.length/pageSize),
lastPage = currentPage+1;

if(filtered.length > pageSize && lastPage < numPages){
return true;
}else if(filtered.length > pageSize && lastPage === numPages){
return false;
}else{
return false;
}
};

return pagination;

});


And then I'm passing the Factory as a dependency in my Controller and calling it like this:

$scope.currentPage = 0;
$scope.pageSize = 10;

$scope.showNext = function(filtered){
PaginationService.showNext(data, $scope.pageSize, $scope.currentPage, filtered);
}


Unfortunately it doesn't work, but no errors are thrown so I'm having trouble diagnosing why that is.

I've also tried making it a Service like this:

this.showNext = function(data, pageSize, currentPage, filtered){
var numPages = Math.ceil(data.length/pageSize),
lastPage = currentPage+1;

if(filtered.length > pageSize && lastPage < numPages){
return true;
}else if(filtered.length > pageSize && lastPage === numPages){
return false;
}else{
return false;
}
};


Then I pass the Service as a dependency and call it in my Controller like this:

$scope.currentPage = 0;
$scope.pageSize = 10;

$scope.showNext = function(filtered){
MyService.showNext(data, $scope.pageSize, $scope.currentPage, filtered);
}


I get the same result, it doesn't work but no errors are thrown.

Overall I'm really just attempting to use this as a shared function between my controllers that I can pass parameters to. Some of those parameters will be $scope variables from the Controller as seen above. I thank you in advance for your help.

Answer

Problem is in implementation in controller

$scope.showNext = function(filtered){
  PaginationService.showNext(data, $scope.pageSize, $scope.currentPage, filtered);
}

Nothing is returned from $scope.showNext() so in view it will always evaluate to undefined

Add return so that the boolean returned by service function gets returned to the controller scope function

$scope.showNext = function(filtered){
   return  PaginationService.showNext(data, $scope.pageSize, $scope.currentPage, filtered);
}