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;

        }
    }
2
  • 1
    Just use limitTo filter on full data array and change the start index each time Commented Dec 20, 2018 at 13:35
  • p.s. docs.angularjs.org/api/ng/filter/limitTo Commented Dec 20, 2018 at 13:36

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

9 Comments

Although I posted an answer that implements manual slicing of data source, I'd say this is more accurate angular way to do it.
@quirimmo thanks for your inputs. I tried adding limit to but somehow its not returning anything. I created a fiddle at jsfiddle.net/aman1981/e3df86a2/9 . I have put the limit to my rows at <tr ng-repeat="r in targetTable.rows | limitTo:limit:start">. 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?
My bad it works now and I can just the first 10 rows. Here is my updated fiddle: 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 change your $scope.start variable when clicking the buttons
I added $scope.start = 20; but nothing happens to the table, stays on same. Updated: jsfiddle.net/aman1981/e3df86a2/20
|
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);
  }

}]);

Comments

-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

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.