0

I have an array of objects as:

[
{ID: "1234", FName: "Steve", LName: "Adams", Status: "New",CreatedBy: "sadams"},
{ID: "5648", FName: "Jon", LName: "Lewis", Status: "New",CreatedBy: "jlewis"},
{ID: "9872", FName: "Hor", LName: "Mt", Status: "Open",CreatedBy: "hmt"},
{ID: "1212", FName: "Allison", LName: "Pan", Status: "New",CreatedBy: "apan"},
...
...so on
]

This data is returned from my API and can be in hundreds.

Now I am using simple HTML table without any third party sources to show this data on the screen and I am using ng-repeat in angularjs to bind this data to the table. Because of so much data I dont want to load entire data at once on the screen. I just want to load first 50 rows and then have a link as "Show next 50". Clicking on which the next 50 rows will be pushed to the array and so on.

This is what I have currently

$http.get('https://myApi').success(function(data) {
    var arr = [];

    //This holds all the data returned
    $scope.dataFromApi = data;

    for (var j = 0; j < 50; j++) {
        //This holds the first 50 rows
        arr.push(data[j]);
    }   

    //This is binding back to the UI
    $scope.tableData = arr;

 }

  $scope.buttonClick = function () {
      //How can I get the next 50 rows from $scope.dataFromApi and add it to $scope.tableData   
  }

How can I get the next 50 rows everytime on the button click and add to the existing array.

Please note that I am not looking for any other third party sources at this moment or any paginations methods.

---Updated---

For anyone else looking for this. I got it resolved as:

Creating a custom filter (as I am using angularjs 1.3.4) as:

app.filter('myLimitTo', function() {
  return function(input, limit, begin) {
    return input.slice(begin, begin + limit);
  };
});

In my html:

  <tr ng-repeat="r in datarows | myLimitTo:limit:start">

Controller:

 $scope.start = 0;
 $scope.limit = 10;

 $scope.next = function () {
        incrementLimit(true)
    }
    $scope.prev = function () {
        incrementLimit(false)
    }

    function incrementLimit(up) {
        if (up) {
            ($scope.start <= ($scope.data.rows.length - $scope.limit)) ? $scope.start += 10 : $scope.start = 0;
        } else {
            $scope.start > 10 ? $scope.start -= 10 : $scope.start = 0;

        }
    }
user1563677
  • 713
  • 3
  • 15
  • 38

3 Answers3

3

Use the limitTo filter:

https://docs.angularjs.org/api/ng/filter/limitTo

HTML:

{{ limitTo_expression | limitTo : limit : begin}}

JS:

$filter('limitTo')(input, limit, begin)

In your case the limit will be a static 50 and you can change the begin through your buttonClick function.

Remember also to add a track by in the repeater with some id/unique of the data returned from the api.

quirimmo
  • 9,800
  • 3
  • 30
  • 45
  • Although I posted an answer that implements manual slicing of data source, I'd say this is more accurate `angular way` to do it. – AdityaParab Dec 20 '18 at 13:50
  • @quirimmo thanks for your inputs. I tried adding limit to but somehow its not returning anything. I created a fiddle at http://jsfiddle.net/aman1981/e3df86a2/9/ . I have put the limit to my rows at . If I remove this limito then I can get the entire data but not with limit to. I also defined start in my controller as $scope.start = 10; . In my fiddle the array is filled at the line where I have my comment as "//Push the data back to the table array." Also one more thing, once this limit is set, where do we apply the filter? – user1563677 Dec 20 '18 at 14:19
  • My bad it works now and I can just the first 10 rows. Here is my updated fiddle: http://jsfiddle.net/aman1981/e3df86a2/14/. Now can you tell me how can I click on next button and have the next 10 rows and so on. – user1563677 Dec 20 '18 at 14:24
  • @user1563677 change your `$scope.start` variable when clicking the buttons – quirimmo Dec 20 '18 at 14:25
  • I added $scope.start = 20; but nothing happens to the table, stays on same. Updated: http://jsfiddle.net/aman1981/e3df86a2/20/ – user1563677 Dec 20 '18 at 14:30
  • I think in your version of angularjs, which is a quite old one, the `limitTo` second parameter was not implemented yet. Are you using the `1.3.4` ? – quirimmo Dec 20 '18 at 14:37
  • check out this link, there is also a custom `myLimitTo` filter implementation ready to go: https://stackoverflow.com/questions/29282082/angular-limitto-filters-second-parameter-begin-does-not-seem-to-work-in-angul – quirimmo Dec 20 '18 at 14:38
  • sorry for being a noob, can you let me know how can I fit this filter to my example and what do I have do in prev and next button/ – user1563677 Dec 20 '18 at 15:03
  • I got it to work now http://jsfiddle.net/aman1981/e3df86a2/24/ . Clicking the next button does shows next results. One last thing remains is the prev button and how to track the changes for next and prev ones thanks – user1563677 Dec 20 '18 at 15:06
0

This is a typical use case known as pagination. The idea is to store current page and current page size (50 in your case) in a variable and refer to this value when user selects next/previous. So what you will do is something like

app.controller('someController', ['$scope', '$http', function($scope, $http){
  $scope.currentPage = 1;
  $scope.numberOfRecordsPerPage = 50;

  $http.get('https://myApi').success(function(data) {
    // ...
    $scope.dataFromApi = data;
    $scope.tableData = data.slice(0, $scope.numberOfRecordsPerPage);
  }

  $scope.buttonClick = function () {
    $scope.currentPage++;

    const startIndex = ($scope.currentPage * $scope.numberOfRecordsPerPage) + 1;
    // if current page is 1, then startIndex will be (1*50)+1 = 51
    // if current page is 2, then startIndex will be (2*50)+1 = 101
    // and so on.

    //Now slice the array from startIndex

    $scope.tableData = data.slice(startIndex, $scope.numberOfRecordsPerPage);
  }

  //similarly you can do so if you want to go back to previous page

  $scope.buttonClickPrev = function () {
    $scope.currentPage--; // in this case you will subtract value by 1

    const startIndex = ($scope.currentPage * $scope.numberOfRecordsPerPage) + 1;    
    $scope.tableData = data.slice(startIndex, $scope.numberOfRecordsPerPage);
  }

}]);
AdityaParab
  • 7,024
  • 3
  • 27
  • 40
-1

why not paging in backend, then you just to fetch data with page? if you want to insist on this way, you can extract for-loop as an function which take page as argument, something like:

const pushDataToTableData = (page, perpage = 50) => {
  arr.push(data.slice(page * perpage, (page + 1) * perpage));
}

call once in success callback, then when clicking, page++ and call this function

Tony_zha
  • 97
  • 6