Search code examples
angularjsselectangularjs-ng-repeatangular-ngmodelng-options

NgModel Inside NgRepeat with Angular Bootstrap DualListbox


As the title of my question implies, I am using Angular Bootstrap DualListbox inside an NgRepeat, but am not having any luck getting the NgModel to work properly. Let me try to mock up what I'm doing below...

ctrl.js

...
$scope.things = mySvc.things;
$scope.vals = mySvc.vals;
...
$scope.selectedVals = [];
$scope.doStuff = function (aThing) {
  $http.post(aUrl, { thing: aThing, val = $scope.selectedVals[0].Value })
    .success(function () {
      ...
    })
    .error(function () {
      ...
    });
};

tmp.html

...
<header ng-repeat-start="thing in things">
  {{thing.Name}}
</header>
<select
 ng-model="selectedVals"
 ng-options="val.Value for val in vals"
 multiple
 bs-duallistbox
>
</select>
<button type="button" class="btn-lg" ng-click="doStuff(thing.Name)">Do Stuff</button>
<br ng-repeat-end />

My issue is that I cannot get $scope.selectedVals to pick up the selections from Angular Bootstrap DualListbox. My $scope.doStuff function is getting called with the thing.Name value passed properly, but I'm seeing an error in my console TypeError: Cannot read property 'Value' of undefined. Furthermore, I can observe through console logging that $scope.selectedVals is, in fact, empty.

I have a more or less identical set-up working in other parts of my web app, but it does not exist in an NgRepeat, so I have to assume that is the problem. Furthermore, I've seen some other posts about issues people have had with NgModel inside NgRepeat (see: here, here, here and here), but I can't really figure out how they relate to a solution to the particular problem that I'm having.

Can anyone point out what I'm doing wrong?


Solution

  • I'm guessing that the main problem is that you probably want to declare the selectedVals Array like this:

    $scope.selectedVals = new Array(mySvc.things.length);
    

    And use it like this in your view:

    <header ng-repeat-start="thing in things">
      {{thing.Name}}
    </header>
    <select
     ngModel="selectedVals[$index]"
     ng-options="val.Value for val in vals"
     multiple
     bs-duallistbox
    >
    </select>
    <button type="button" class="btn-lg" ng-click="doStuff(thing.Name, selectedVals[$index])">Do Stuff</button>
    <br ng-repeat-end />
    

    And then your doStuff function should be something like this:

    $scope.doStuff = function (aThing, selectedVal) {
      $http.post(aUrl, { thing: aThing, val = selectedVal)
        .success(function () {
          ...
        })
        .error(function () {
          ...
        });
    };