2

just a quick Question!

I have an ordering function, which is supposed to order two arrays depending on the situation. So i pass the array reference, but the array is not filtered! Any ideas?

function order(rowName, array) {
    if (vm.row === rowName) {
        return;
    }

    vm.row = rowName;
    array = $filter('orderBy')(array, rowName);
    return vm.onOrderChange();
};

which is called in my html as :

data-ng-click = "vm.order('amount', vm.itemsNew)"

i got it working like below, but... well, i don't like it!

function order(rowName, array) {
    if (vm.row === rowName) {
        return;
    }

    vm.row = rowName;
    if (array === vm.itemsNew)
        vm.itemsNew = $filter('orderBy')(vm.itemsNew, rowName);
    else
        vm.itemsGeneric = $filter('orderBy')(vm.itemsGeneric, rowName);
    return vm.onOrderChange();
};
Victor Benetatos
  • 396
  • 3
  • 12
  • Can you add any fiddle/plnkr? – Khalid Hussain Mar 30 '16 at 09:34
  • 1
    Is it even necessary to pass the array? Can `order` be called for other arrays too? – a better oliver Mar 30 '16 at 09:39
  • @zeroflagL Originally there was one array to be sorted, so there was no need for a second argument in the function. But then a new one became necessary, so i just thought to pass a reference to the array i want to sort instead. – Victor Benetatos Mar 30 '16 at 09:47
  • I don't know what's the point of returning the result of `vm.onOrderChange();`, but it should be possible to return `array` and have `data-ng-click = "vm.itemsNew = vm.order('amount', vm.itemsNew)"` – a better oliver Mar 30 '16 at 09:57
  • @zeroflagL That did the trick, thanks. The vm.onOrderChange(); just changes ta pagination page to 1, when the order changes. I just merged it with return to save a line. – Victor Benetatos Mar 30 '16 at 10:17

2 Answers2

1

This line tries to change reference to array which is argument of the function.

array = $filter('orderBy')(array, rowName);

Simple answer is that you can't change original reference inside of the function. This is why vm.itemsNew = $filter('orderBy')(vm.itemsNew, rowName); working correctly.

You can read more here: Is JavaScript a pass-by-reference or pass-by-value language?

Good thing is that you are seeing that your solution is very ugly ;)

You can use filter and rewrite array like this:

    function order(rowName, array) {
        if (vm.row === rowName) {
            return;
        }

        vm.row = rowName;
        var tmpArray = $filter('orderBy')(array, rowName);
        array.length = 0; //clears array
        angular.forEach(tmpArray, function(item) { // fill array with ordered values from tmpArray.
            array.push(item);
        });
        return vm.onOrderChange();
    };

Obviously, this is not the best from performance point of view. I highly recommend you to learn more about passing arguments to functions in JS. Link above is good starting point.

Community
  • 1
  • 1
rzelek
  • 3,975
  • 1
  • 33
  • 35
0

ng-click not only allows you to call a function but to evaluate arbitrary expressions. So you can return the filtered array from your function and assign it to the model:

data-ng-click = "vm.itemsNew = vm.order('amount', vm.itemsNew)"

The function:

...
array = $filter('orderBy')(array, rowName);
vm.onOrderChange();
return array;
a better oliver
  • 26,330
  • 2
  • 58
  • 66