Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular UI Select2, why does ng-model get set as JSON string?

I'm using angular-ui's select2 for a fairly simple dropdown. It's backed by a static array of data sitting on my controller's scope. In my controller I have a function that gets called on ng-change of the dropdown so that I can perform some actions when the value changes.

However, what I'm finding is that the ng-model's property gets set as a JSON string rather than an actual javascript object, which makes it impossible to use dot notation to grab properties off of that model.

Here's the function that handles the value of the dropdown getting changed:

$scope.roleTypeChanged = function() {
  //fine:
  console.log('selectedType is: ', $scope.adminModel.selectedType);

  // this ends up being undefined because $scope.adminModel.selectedType is a 
  // JSON string, rather than a js object:
  console.log('selectedType.typeCode is: ', $scope.adminModel.selectedType.typeCode);
}

Here's a plunker of my full example: http://plnkr.co/edit/G39iZC4f7QH05VctY8zG

I've never seen a property that's bound to ng-model do this before, however I'm also fairly new to Angular so it's likely that I'm just doing something wrong here. I can certainly do something like $.parseJSON() to convert the JSON string back to an object, but I'd rather not unless I have to. Thanks for any help!

like image 613
Graff Vynda-K Avatar asked Jul 08 '13 20:07

Graff Vynda-K


2 Answers

You need to use ng-options on your select if you want to have object values. Actually creating the options yourself using an ng-repeat will only allow you to have string values for the various options:

<select ui-select2
    ng-model="adminModel.selectedType"
    ng-change="roleTypeChanged()"
    data-placeholder="Select Role Type" ng-options="type.displayName for type in adminModel.roleTypes">
  <option value=""></option>
</select>

http://plnkr.co/edit/UydBai3Iy9GQg6KphhN5?p=preview

like image 56
Karen Zilles Avatar answered Nov 02 '22 13:11

Karen Zilles


Thanks Karl! I have struggled a day with this

as a note for others having similar problems as I did, when using an ng-model not accessible and defined in the controller/directive I solved it like this.

//country.Model has Code and Name nodes

* HTML *

 <select 
name="country" data-ng-model="country.Model"  
    data-ui-select2=""  
    data-ng-change="countryChanged(country.Model)"  <!--only for test, log to console-->
    data-ng-options="country as CodeAndName(country) for country in countries"
    data-placeholder="{{placeholderText(country.Model, '- - Select Country - -')}}" >
    <option value=""></option>
</select>  

* JS *

 function controller($scope, $q, $location, $routeParams) {

    $scope.countryChanged = function(item) { // for test                
      console.log('selectedType is: ', item);
    };

    //returns the item or the text if no item is selected
    $scope.placeholderText = function (item, text){ 
        if (item == undefined)
            return text;
        return $scope.CodeAndName(item);
    };

    // returns a string for code and name of the item, used to set the placeholder text
    $scope.CodeAndName = function (item) { 
        if (item == undefined)
            return '';
        return item.Code + ' - ' + item.Name;
    };
like image 24
JimiSweden Avatar answered Nov 02 '22 14:11

JimiSweden