Setting a default <select> with asynchronous data

I have a drop down list

<select ng-model="referral.organization" ng-options="key as value for (key, value) in organizations"> </select> 

where organizations populated using the $ http request. I also have a referral resource that includes several properties, including an organization integer corresponding to the value stored in the drop-down list. Currently the dropdown menu works fine and choosing a new value will update my referral resource without any problems.

However, when the page loads, the drop-down list is empty, and the value of referral.organization that was extracted from the server (that is, when opening the previously saved referral form) is not displayed. I understand that this is probably due to the fact that my resource is empty when the first page loads, but how can I update the drop-down list when the information has been successfully restored?

Edit: {{ organizations[referral.organization] }} successfully displays the selected value if it is placed somewhere else on the page, but I donโ€™t know how to specify a tag to display this expression.

Second edit: The problem was apparently a mismatch between the key used in ngOptions and the variable used in ngModel. The <select> option was returned as strings from the WebAPI (despite the start of the dictionary), while the referral model returned integers. When referral.organization was placed in ngModel, Angular did not match 2723 and "2723", etc.

I tried several different things, but the following works well and is the โ€œcleanestโ€ for me. In the callback for the $ resource GET, I simply change the necessary variables to strings as follows:

 $scope.referral = $resource("some/resource").get(function (data) { data.organization = String(data.organization); ... }); 

Not sure if this will be considered a problem with Angular (doesn't match 1000 by "1000") or WebAPI (serialization Dictionary<int,String> to { "key":"value" } ), but it's functional, and the <select> still linked to the referral resource.

+4
angularjs
source share
3 answers

Other answers were correct in the sense that it usually "just works." The problem was ultimately a mismatch between the organization key (integer) stored inside $scope.organizations and the key that is stored in the $http response, which is stored in JSON and therefore as a string. Angular did not match the string integer. As I mentioned in my editing on the original question, the solution at that time was to pass the response data of $http to a string. I'm not sure if current versions of Angular.js still behave this way.

0
source share

For simple types, you can simply set $scope.referral.organization , and this will magically work:

http://jsfiddle.net/qBJK9/

 <div ng-app ng-controller="MyCtrl"> <select ng-model="referral.organization" ng-options="c for c in organizations"> </select> </div> 

-

 function MyCtrl($scope) { $scope.organizations = ['a', 'b', 'c', 'd', 'e']; $scope.referral = { organization: 'c' }; } 

If you use objects, it gets harder because Angular does not look smart enough to know that the new object is practically the same. If there is no Angular hack, the only way I can see ahead is to update $scope.referral.organization after it is downloaded from the server and assign it a value from $scope.organizations , for example:

http://jsfiddle.net/qBJK9/2/

 <div ng-app ng-controller="MyCtrl"> <select ng-model="referral.organization" ng-options="c.name for c in organizations"></select> {{referral}} <button ng-click="loadReferral()">load referral</button> </div> 

-

 function MyCtrl($scope) { $scope.organizations = [{name:'a'}, {name:'b'}, {name:'c'}, {name:'d'}, {name:'e'}]; $scope.referral = { organization: $scope.organizations[2] }; $scope.loadReferral = function () { $scope.referral = { other: 'parts', of: 'referral', organization: {name:'b'} }; // look up the correct value angular.forEach($scope.organizations, function(value, key) { if ($scope.organizations[key].name === value.name) { $scope.referral.organization = $scope.organizations[key]; return false; } }); }; } 
+3
source share

You can assign referral.organization one of the objects derived from ajax:

 $scope.referral.organization = $scope.organizations[0] 

I created a simple demo in plunker . The button click handler modifies the list of objects and selects one by default.

 $scope.changeModel = function() { $scope.listOfObjects = [{id: 4, name: "miss1"}, {id: 5, name: "miss2"}, {id: 6, name: "miss3"}]; $scope.selectedItem = $scope.listOfObjects[1]; }; 
0
source share

All Articles