Rafael Eduardo Paulin
Rafael Eduardo Paulin

Reputation: 333

Angular passing a variable as function aprameter and dealing within

I got the following issue: I need to pass schoolList to the ngClick function as a parameter (to be possible to re-use the function with other arrays). But when I try to deal with the array inside the function, using the 'group' local variable, it does not update the array itself.

if I use 'scope.schoolsList' instead of 'group' in the function, everything works fine.

is there a way to deal with this and make it work?

relevant par of my directive:

link: {
            scope.schoolsList = [
                'item 1',
                'item 2',
                'item 3',
                'item 4',
            ];

            scope.addItem = function(obj, array, group){
                array.push(obj);

                group = group.filter(function(list){
                    return list !== obj;
                });

            };
            scope.removeItem  = function($index, group){
                group.push(scope.newData.schools[$index]);
                scope.newData.schools.splice($index,1);
                console.log(scope.newData.schools);
            }
        }

Relevant par of the html

<select id="newSchool" name="newSchool" ng-model="newSchool" ng-options="school for school in schoolsList | orderBy:school">
    <option value="" hidden>-- Select --</option>
</select>
<a ng-click="addItem(newSchool, newData.schools, schoolsList)">add</a>
<ul class="list-inline">
    <li ng-show="newData.schools.length > 0">
        <ng-pluralize count="newData.schools.length" 
                      when="{'0': '','one': 'School: ','other': 'Schools: '}">
        </ng-pluralize>
    </li>
    <li ng-repeat="school in newData.schools">
        <span>{{ school }}</span>
        <a ng-click="removeItem($index, schoolsList)">[X]</a>
    </li>
</ul>

Upvotes: 1

Views: 72

Answers (3)

Jonathan Rupp
Jonathan Rupp

Reputation: 15762

To do this, you'll need to modify the group array that's passed into addItem, such as with splice.

Say, something like this (untested):

scope.addItem = function(obj, array, group){
    array.push(obj);

    for(var i=0; i<group.length; i++) {
        if(group[i] !== list) {
            group.splice(i, 1); // splice modifies the array
            i--; // need to check spot 'i' again
        }
    }
};

Upvotes: 1

Andr&#233;s Esguerra
Andr&#233;s Esguerra

Reputation: 861

The problem is you're reassigning the variable group. When the function starts, group has a reference to the same object as schoolList, but when you do group = group.filter... you're creating a new array, and referencing group to it, so any change to it is not linked to schoolList. When the function ends, you don't do anything with it, so is the same as not having it.

I don't clearly understand the purpose of your directive, but if you want to reuse the whole directive, you should define an isolate scope with two-way binding for collections. If you don't want to reuse the whole directive, but just that single function, please provide more information about the purpose of the directive itself.

Upvotes: 1

FesterCluck
FesterCluck

Reputation: 320

This has to do with how Javascript handles references. AngularJS relies heavily on them to do things properly. The best rule of thumb to prevent breaking references is to always make changes to properties of an object/variable, and never the variable itself. Here's another perspective on your issue.

link: {
        scope.data.schoolsList = [
            'item 1',
            'item 2',
            'item 3',
            'item 4',
        ];

        scope.addItem = function(obj, array, group){
            array.push(obj);

            group.schoolList = group.schoolList.filter(function(list){
                return list !== obj;
            });

        };
        scope.removeItem  = function($index, group){
            group.schoolList.push(scope.newData.schools[$index]);
            scope.newData.schools.splice($index,1);
            console.log(scope.newData.schools);
        }
    }


<select id="newSchool" name="newSchool" ng-model="newSchool" ng-options="school for school in data.schoolsList | orderBy:school">
    <option value="" hidden>-- Select --</option>
</select>
<a ng-click="addItem(newSchool, newData.schools, data)">add</a>
<ul class="list-inline">
    <li ng-show="newData.schools.length > 0">
        <ng-pluralize count="newData.schools.length" when="{'0': '','one': 'School: ','other': 'Schools: '}"></ng-pluralize>
    </li>
    <li ng-repeat="school in newData.schools"><span>{{school}} </span> <a ng-click="removeItem($index, data)">[X]</a></li>
</ul>

Upvotes: 0

Related Questions