Search code examples
angularjsstringtypeahead

How to order strings by length with orderBy filter?


I have this code which work as expected providing me all the items starting with the letters I type in :

<input name="search-bar" id="search-bar" type="text"  ng-model="search" 
typeahead="res.label for res in result | filter:$viewValue:startsWith | 
limitTo:20">

But I want the suggestions to be ordered by the length of the label, so I tried two things without any luck :

1st try

<input name="search-bar" id="search-bar" type="text" ng-model="search" 
typeahead="res.label for res in result | filter:$viewValue:startsWith | 
limitTo:20 | orderBy:'res.label'">

2nd try

<input name="search-bar" id="search-bar" type="text" ng-model="search"
typeahead="res.label for res in result | filter:$viewValue:startsWith | 
limitTo:20 | orderBy:'res.label.length'">

EDIT (controller code) :

var url = "/data/list.json";
var items = $http.get(url).then(function(response){
        $scope.result = response.data; //result is filled with a static json containing all the data
        $scope.loading = false;
    });

JSON sample (from /data/list.json) :

[{"code":64,"label":"ALPAGA (64)"},{"code":44,"label":"ALPA (44)"}]

What am I missing ?


Solution

  • You can use a custom orderBy routine like in this runnable fiddle demo or just try orderBy:'label.length' which directly interacts with the iterated object attribute. Both approaches should work for you in a fine way.

    View

    <div ng-controller="MyCtrl">
      <div ng-repeat="item in data | orderBy:orderByLength">
          {{ item.label }}
      </div>
    </div>
    

    AngularJS application

    var myApp = angular.module('myApp', []);
    
    myApp.controller('MyCtrl', function($scope) {
      $scope.data = [{
        "code": 64,
        "label": "ALPAGA (64)"
      }, {
        "code": 44,
        "label": "ALPA (44)"
      }, {
        "code": 24,
        "label": "ALPA (12344)"
      }, {
        "code": 48,
        "label": "ALPA (42324df)"
      }];
    
      $scope.orderByLength = function (item) {
          return item.label.length
      }
    });