2

I am making a small Contacts application with Bootstrap 4 and AngularJS v1.6.6.

The application simply displays an Users JSON. Since the JSON returns a large number of users, the application also has a pagination feature.

The pagination worked fine as part of the app's controller, but since I tried to turn it into a service, it does not work anymore.

See a functional version of the application, with the pagination inside the controller HERE.

The application controller:

// Create an Angular module named "contactsApp"
var app = angular.module("contactsApp", []);

// Create controller for the "contactsApp" module
app.controller("contactsCtrl", ["$scope", "$http", "$filter", "paginationService", function($scope, $http, $filter) {
  var url = "https://randomuser.me/api/?&results=100&inc=name,location,email,cell,picture";
  $scope.contactList = [];
  $scope.search = "";
  $scope.filterList = function() {
    var oldList = $scope.contactList || [];
    $scope.contactList = $filter('filter')($scope.contacts, $scope.search);
    if (oldList.length != $scope.contactList.length) {
      $scope.pageNum = 1;
      $scope.startAt = 0;
    };
    $scope.itemsCount = $scope.contactList.length;
    $scope.pageMax = Math.ceil($scope.itemsCount / $scope.perPage);
  };

  $http.get(url)
    .then(function(data) {
      // contacts arary
      $scope.contacts = data.data.results;
      $scope.filterList();

      // Pagination Service
      $scope.paginateContacts = function(){
        $scope.pagination = paginationService.paginateContacts();
      }

    });
}]);

The service:

app.factory('paginationService', function(){
     return {
        paginateContacts:  function(){
            // Paginate
            $scope.pageNum = 1;
            $scope.perPage = 24;
            $scope.startAt = 0;
            $scope.filterList();

            $scope.currentPage = function(index) {
                $scope.pageNum = index + 1;
                $scope.startAt = index * $scope.perPage;
            };

            $scope.prevPage = function() {
                if ($scope.pageNum > 1) {
                    $scope.pageNum = $scope.pageNum - 1;
                    $scope.startAt = ($scope.pageNum - 1) * $scope.perPage;
                }
            };

            $scope.nextPage = function() {
                if ($scope.pageNum < $scope.pageMax) {
                    $scope.pageNum = $scope.pageNum + 1;
                    $scope.startAt = ($scope.pageNum - 1) * $scope.perPage;
                }
            };
        }
    }
});

In the view:

<div ng-if="pageMax > 1">
        <ul class="pagination pagination-sm justify-content-center">
            <li class="page-item"><a href="#" ng-click="prevPage()"><i class="fa fa-chevron-left"></i></a></li>
            <li ng-repeat="n in [].constructor(pageMax) track by $index" ng-class="{true: 'active'}[$index == pageNum - 1]">
                <a href="#" ng-click="currentPage($index)">{{$index+1}}</a>
            </li>
            <li><a href="#" ng-click="nextPage()"><i class="fa fa-chevron-right"></i></a></li>
        </ul>
</div>

The service file is included in the project (correctly, in my opinion) after the app.js file:

<script src="js/app.js"></script>
<script src="js/paginationService.js"></script>

I am not an advanced AngularJS user so I don't know: what is missing?

Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58
Razvan Zamfir
  • 4,209
  • 6
  • 38
  • 252
  • "does not work" is not helpful. Tell us what the expected behavior should be. Tell us what the exact wording of the error message is, and which line of code is producing it. Put a brief summary of the problem in the title of your question. – georgeawg Dec 08 '18 at 15:11
  • @georgeawg It should be like **[this one](https://codereview.stackexchange.com/questions/203089/paginated-angularjs-posts-application/209227)**. – Razvan Zamfir Dec 08 '18 at 18:37
  • Start with opening the Developer Console and discovering the error messages. – georgeawg Dec 08 '18 at 18:52
  • Possible duplicate of [Injecting $scope into an angular service function()](https://stackoverflow.com/questions/22898927/injecting-scope-into-an-angular-service-function). – georgeawg Dec 08 '18 at 18:55

1 Answers1

1

It appears that the service needs to be defined before the controller, otherwise it cannot be injected properly.

So you could either move the paginationService into app.js:

var app = angular.module("contactsApp", []);
app.factory('paginationService', function(){
    //...
});
app.controller("contactsCtrl", ["$scope", "$http", "$filter", "paginationService", function($scope, $http, $filter) {
    //...
});

Or else move the controller out to a separate file that is included after the paginationServices.js file.

Take a look at this plunker. Try modifying line 6 - remove character 5, i.e. the space that separates the star and slash that would close the multi-line comment.

Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58