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

2

9

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!

Westland answered 8/7, 2013 at 20:37 Comment(0)
M
6

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

Marisolmarissa answered 8/7, 2013 at 20:50 Comment(3)
Interesting, that makes sense but I didn't bother trying that because according to the documentation ng-options isn't supported: github.com/angular-ui/ui-select2Westland
I haven't worked with ui-select2, so perhaps there are undesirable side effects to this solution. In any case, if you're going to use an ng-repeat on options, you will have to deal with simple strings instead of full blown objects.Marisolmarissa
Thanks for the help. I may ask this same question on the github page for ui-select2 just to see if supporting ng-options is on the roadmap or if there are reasons for not supporting it. I can probably do some tweaks to make my use-case work with strings rather than a full object.Westland
A
2

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;
    };
Absurdity answered 6/3, 2014 at 15:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.