Reputation: 7279
I have the following data that I got from a third-party:
countries: [
{"US":"United States"},
{"CA":"Canada"},
{"AF":"Afghanistan"},
{"AL":"Albania"},
{"DZ":"Algeria"},
{"DS":"American Samoa"},
.....
];
The way the data is organized is not how I would have done it, but now I need fit all of this in a select with ng-options so that both the value and the option displayed is the full name of the country
I have tried ng-options="code as name for (code, name) in countries"
but I get an Object as my select value.
Upvotes: 2
Views: 6874
Reputation: 7632
I was in the process of asking nearly the identical question as you when Stack Overflow suggested I look at your question. Looks like we got our Country list from the same source. I didn't want to change the structure either. But after seeing the accepted answer, I didn't want to hack it that way. So instead I wrote a reusable service that will Morph any similar data structure.
The Service
/*
* Morphs an array of a key/val pair to have the original key, be a value, and
* give new property names
*
* @method keyValMorph
* @param {array of objects} ex: [ {US:'United States'} ]
* @param {string} keyName - desired property name for the original key
* @param {string} valName - desired property name for the original value
* @return {array of objects} ex: [ {key: 'US', val: 'United States'} ]
*/
.factory('keyValMorph', function () {
return function (data, keyName, valName) {
var sort = [], keyName = keyName || 'key', valName = valName || 'val';
for (var i = 0; i < data.length; i++) {
var obj = {};
for (var key in data[i]) {
obj[keyName] = key;
obj[valName] = data[i][key];
sort.push(obj);
}
}
return sort;
};
})
The controller call:
$scope.countriesSorted = keyValMorph($scope.countries, 'code', 'name');
It'll take your original data structure and turn it into:
$scope.countriesSorted = [
{code:"US", name:"United States"},
{code:"CA", name:"Canada"},
{code:"AF", name:"Afghanistan"},
{code:"AL", name:"Albania"},
{code:"DZ", name:"Algeria"},
{code:"DS", name:"American Samoa"}
];
HTML
<select data-ng-model="selected" data-ng-options="country.code as country.name for country in countriesSorted ">
<option value="">[-- select --]</option>
</select>
Upvotes: 2
Reputation: 1118
Working plunkr here: http://plnkr.co/edit/nbWHz8g4Gn0vGuSHM5o0?p=preview
Though as Nicolas pointed out, it's probably better to transform the data?
HTML:
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="[email protected]" data-semver="1.2.14" src="http://code.angularjs.org/1.2.14/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="AppCtrl">
<select id="countries" name="countries" ng-model="selectedCountry"
ng-options="getKey(country) as country[getKey(country)] for country in countries"></select>
Selected country: {{selectedCountry}}
</body>
</html>
JS:
// Code goes here
angular.module('app',[]).controller("AppCtrl", ["$scope", function($scope) {
$scope.countries = [
{"US":"United States"},
{"CA":"Canada"},
{"AF":"Afghanistan"},
{"AL":"Albania"},
{"DZ":"Algeria"},
{"DS":"American Samoa"}
];
$scope.getKey = function(country) {
return Object.keys(country)[0];
}
}]);
Upvotes: 5
Reputation: 1335
Here is a sample from my own project:
data-ng-options="task.name for task in tasks track by task.id"
I am sure you can adapt it to your own.
Upvotes: 1