Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm new to AngularJS, so bare with me. Firstly, I'm using AngularJS in parts of my website, not for the whole thing. I have a couple of select boxes with one that is dependent on the other. One contains a list of countries, and the other contains cities for the selected country.

In the past, I would split my json into 2 queries to the server, so on country changed, it'll send the selected value, and the server would return a json list accordingly which will be inserted into the select box using jquery. This time, and using http://builtwith.angularjs.org/ as sort of a guideline, I decided to return everything as one json, and handle this functionality purely in javascript.

So lets say, my json looks like this:

[
  { "code": 1, "country": "Germany", "cities": [ "Berlin", "Munich" ] },
  { "code": 2, "country": "Italy", "cities": [ "Rome", "Venice" ] },
  { "code": 3, "country": "United Kingdom", "cities": [ "London", "Manchester" ]}
]

I would need all the values of country as one list for country select box, and the list of each cities for the other select box.

Here's the controller so far:

angular.module('myApp', [])
    .controller('MyController', ['$scope', '$http', function ($scope, $http) {


        $http.get('/api/locations')
            .success(function (data, status, header, config) {

                $scope.locations = data[0];
                $scope.countryList = [];
                $scope.cityList = [];

                for (var i = 0; i < data.length; i++) {
                    $scope.countryList.push([data[i].code, data[i].country]);
                    for (var j = 0; j < data[i].cities.length; j++) {
                        $scope.cityList.push([data[i].code + '-' + data[i].cities[j], data[i].cities[j]]);
                    }
                }
            });
    }]);

My select boxes:

Country:

<select ng-model="country" data-ng-options="c for c in countryList"></select>

City:

<select data-ng-model="city" data-ng-options="c for c in cityList"></select>

Currently, both select boxes get filled, but their text contains both values of the array. The cities box contains ALL cities, not just the ones for the first country.

I'm not sure if i'm on the right path here, or if there's an easier way to achieve this.

So sum up, I'd like to know:

  1. Should i keep the whole json as one request/response and handle it in JS?
  2. How do you load each select box the 'official' angularjs way?
  3. I'm aware of the ng-change attribute on the select box, but I'm not sure how I'd create a query and change the city list values according to the selected country.

Here is a plunk: http://plnkr.co/edit/zAcRjSDm9OndxugtsAOs?p=preview

Thanks!

share|improve this question
add comment

1 Answer

up vote 2 down vote accepted

I'm not sure if i'm on the right path here, or if there's an easier way to achieve this.

Yes you are on the path of The Angular Way. And yes, there is an easier way.

I'm aware of the ng-change attribute on the select box, but I'm not sure how I'd create a query and change the city list values according to the selected country.

Here is a forked Plunk that demonstrates how to set the 2nd select box based on the output of the first.

The country select box has 2way binding via ng-model, so the result is bound to a value called country

The country select box uses country.cities for it's inputs, and binds the selected value to city

Should i keep the whole json as one request/response and handle it in JS?

That depends on how you build your service. If you forsee no use of separating cities from countries, then keep them bounded.

Otherwise you may wish to have the following REST api:

get /country //returns array of all countries
get /<countryname>/cities //returns array of all cities in country

The downside is that you need to make multiple get requests for the data. The upside is your api is a bit more modular. However it depends on your use case.

How do you load each select box the 'official' angularjs way?

Your plunk syntax 'c for c in cityList' appears correct.

share|improve this answer
 
Thanks for that. I think i've pretty much got it. Two more quick questions though: Should i use ngResource factory for calling the json, or stick with $http? And, how the hell do you get it to select the first option automatically? Cheers :) –  jzm Apr 16 '13 at 5:22
 
I worked it out. Here's a forked plunk of it working with ngResource and auto selecting values, but it's using ng-change for auto select of first item. is this optimal? plnkr.co/edit/0n6CiDhTs3xkKo6cZd1h?p=preview –  jzm Apr 16 '13 at 5:52
 
Use ngResource if you're using RESTful services, and if you're looking to do more than very basic gets. $http is a lower level service helper that provides nice wrapper over XHR/JSONP. It would be better to not have to used a "changed" function in the controller, and instead use ng-init, however, ng-init will execute before your JSON data is loaded, so it won't pick the appropriate values, so I'm pretty sure your update solution is correct. –  Alan Apr 16 '13 at 6:14
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.