2

I have an ng-repeat as following :

<ul>
   <li ng-repeat="o in villes | limitTo:5"><a href="#">{{o.nomVille}}</a></li>
</ul>

I want to reorder the villes list randomly before I limit it to 5, so every time I open my page I get 5 different villes each time.

is there a filter in angularjs who can do that for me ?

edit :

I created a costum filter to randomize that list as following :

.filter('random', function() {
  return function(val) {
    let shuffle = (a) => {
      let r = [];
      while (arr.length)
        r.push(
          arr.splice( (Math.floor(Math.random() * arr.length)) , 1)[0]
        );

      return shuffle(val);
    }
  };
});

and in ng-repeat I did this :

<li ng-repeat="o in villes | random | limitTo:5"><a href="#">{{o.nomVille}}</a></li>

but I cant no longer see anything in my page.

this is the example on jsfiddle : https://jsfiddle.net/z10wwhcv/

Community
  • 1
  • 1
Renaud is Not Bill Gates
  • 1,684
  • 34
  • 105
  • 191

4 Answers4

0

You'd have to build a custom filter function that randomizes the order and then apply the filters in the correct order (random before limit).

Have a look at this for details:

Using AngularJS how could I randomize the order of a collection?

Community
  • 1
  • 1
  • how can I define some filter using that random function ? since I want to use it for multiple controllers ? – Renaud is Not Bill Gates Mar 17 '16 at 16:06
  • In that case have a look at actually defining it as a filter (as opposed to a controller function which it is now). The angular doc for custom filters can be found here: https://docs.angularjs.org/tutorial/step_09 –  Mar 17 '16 at 16:12
  • If you look at the JS console you'll probably find that one of your dependencies is missing. If that happens angular doesn't render the rest of the page. –  Mar 17 '16 at 16:26
  • I dont think so since I dont get anything in console – Renaud is Not Bill Gates Mar 17 '16 at 16:31
0

If you want the order to change each time you load the page you can't do it as a filter as that will presumably change on each digest cycle. You need to store villes on the scope somewhere and generate it in a random order when the page loads, e.g. in your controller function for that page.

Mike Jerred
  • 9,551
  • 5
  • 22
  • 42
0

use the filter in the controller (which is also a best practice performance boost):

$scope.shuffled = $filter('random',$scope.villes)

you'll need to inject the service in the controller


this is what your filter should look like ( not tested but should work ):

 .filter('random', function() {
          return function(a) {

              var r = [];
              while (a.length)
                r.push(
                  a.splice((Math.floor(Math.random() * a.length)), 1)[0]
                );
              return r;
          }
        }
maioman
  • 18,154
  • 4
  • 36
  • 42
  • @AimadMAJDOU your fiddle wasn't working principally because you had some syntax errors; here's the debugged version using filter inside controller - https://jsfiddle.net/maio/z10wwhcv/1/ – maioman Mar 18 '16 at 18:31
0

This is the solution I created :

shufflemodule.filter('shuffle', function() {
    var shuffledArr = [],
        shuffledLength = 0;
    return function(arr) {
        var o = arr.slice(0, arr.length);
        if (shuffledLength == arr.length) return shuffledArr;
        for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
        shuffledArr = o;
        shuffledLength = o.length;
        return o;
    };
});

http://jsfiddle.net/aimad_majdou/6mngvo38/

Renaud is Not Bill Gates
  • 1,684
  • 34
  • 105
  • 191