Limiting number of displayed results when using ngRepeat

JavascriptModel View-ControllerAngularjsScope

Javascript Problem Overview


I find the AngularJS tutorials hard to understand; this one is walking me through building an app that displays phones. I’m on step 5 and I thought as an experiment I’d try to allow users to specify how many they’d like to be shown. The view looks like this:

<body ng-controller="PhoneListCtrl">

  <div class="container-fluid">
    <div class="row-fluid">
      <div class="span2">
        <!--Sidebar content-->

        Search: <input ng-model="query">
        How Many: <input ng-model="quantity">
        Sort by:
        <select ng-model="orderProp">
          <option value="name">Alphabetical</option>
          <option value="age">Newest</option>
        </select>

      </div>
      <div class="span10">
        <!--Body content-->

        <ul class="phones">
          <li ng-repeat="phone in phones | filter:query | orderBy:orderProp">
            {{phone.name}}
            <p>{{phone.snippet}}</p>
          </li>
        </ul>

      </div>
    </div>
  </div>
</body>

I’ve added this line where users can enter how many results they want shown:

How Many: <input ng-model="quantity">

Here’s my controller:

function PhoneListCtrl($scope, $http) {
  $http.get('phones/phones.json').success(function(data) {
    $scope.phones = data.splice(0, 'quantity');
  });

  $scope.orderProp = 'age';
  $scope.quantity = 5;
}

The important line is:

$scope.phones = data.splice(0, 'quantity');

I can hard-code in a number to represent how many phones should be shown. If I put 5 in, 5 will be shown. All I want to do is read the number in that input from the view, and put that in the data.splice line. I’ve tried with and without quotes, and neither work. How do I do this?

Javascript Solutions


Solution 1 - Javascript

Slightly more "Angular way" would be to use the straightforward limitTo filter, as natively provided by Angular:

<ul class="phones">
  <li ng-repeat="phone in phones | filter:query | orderBy:orderProp | limitTo:quantity">
    {{phone.name}}
    <p>{{phone.snippet}}</p>
  </li>
</ul>

app.controller('PhoneListCtrl', function($scope, $http) {
    $http.get('phones.json').then(
      function(phones){
        $scope.phones = phones.data;
      }
    );
    $scope.orderProp = 'age';
    $scope.quantity = 5;
  }
);

PLUNKER

Solution 2 - Javascript

A little late to the party, but this worked for me. Hopefully someone else finds it useful.

<div ng-repeat="video in videos" ng-if="$index < 3">
    ...
</div>

Solution 3 - Javascript

here is anaother way to limit your filter on html, for example I want to display 3 list at time than i will use limitTo:3

  <li ng-repeat="phone in phones | limitTo:3">
    <p>Phone Name: {{phone.name}}</p>
  </li>

Solution 4 - Javascript

store all your data initially

function PhoneListCtrl($scope, $http) {
  $http.get('phones/phones.json').success(function(data) {
    $scope.phones = data.splice(0, 5);
    $scope.allPhones = data;
  });

  $scope.orderProp = 'age';
  $scope.howMany = 5;
  //then here watch the howMany variable on the scope and update the phones array accordingly
  $scope.$watch("howMany", function(newValue, oldValue){
    $scope.phones = $scope.allPhones.splice(0,newValue)
  });
}

EDIT had accidentally put the watch outside the controller it should have been inside.

Solution 5 - Javascript

This works better in my case if you have object or multi-dimensional array. It will shows only first items, other will be just ignored in loop.

.filter('limitItems', function () {
  return function (items) {
    var result = {}, i = 1;
    angular.forEach(items, function(value, key) {
      if (i < 5) {
        result[key] = value;
      }
      i = i + 1;
    });
    return result;
  };
});

Change 5 on what you want.

Solution 6 - Javascript

Use limitTo filter to display a limited number of results in ng-repeat.

<ul class="phones">
      <li ng-repeat="phone in phones | limitTo:5">
        {{phone.name}}
        <p>{{phone.snippet}}</p>
      </li>
</ul>

Solution 7 - Javascript

Another (and I think better) way to achieve this is to actually intercept the data. limitTo is okay but what if you're limiting to 10 when your array actually contains thousands?

When calling my service I simply did this:

TaskService.getTasks(function(data){
    $scope.tasks = data.slice(0,10);
});

This limits what is sent to the view, so should be much better for performance than doing this on the front-end.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCaptain StackView Question on Stackoverflow
Solution 1 - JavascriptStewieView Answer on Stackoverflow
Solution 2 - JavascriptcouzziView Answer on Stackoverflow
Solution 3 - JavascriptRizwanView Answer on Stackoverflow
Solution 4 - JavascriptshaunhusainView Answer on Stackoverflow
Solution 5 - JavascriptfdrvView Answer on Stackoverflow
Solution 6 - JavascriptRajkiran ShettyView Answer on Stackoverflow
Solution 7 - JavascriptMatt SaundersView Answer on Stackoverflow