0

I'm trying to write a directive for dependant select elements. The relationship is Country > States > Cities. When element with class country get changed I should update element with class states and the same behavior for element with class city. To get the states I only need the country id and for get cities I need country and state id's. So I did this code:

app.directive('country', ['$http', function($http) {
        return {
            restrict: 'C',
            link: function(scope, element, attrs) {
                element.change(function() {
                    $http.get(Routing.generate('states') + '/' + element.val()).success(function(data) {
                        if (data.message) {
                            scope.message = data.message;
                        } else {
                            scope.states = data;
                        }
                    }).error(function(data, status, headers, config) {
                        if (status == '500') {
                            scope.message = "No hay conexión con el servidor.";
                        }
                    });

                    console.log(scope.states);
                    console.log(scope.message);

                });
            }
        }
    }]);

But console.log() statements logs "undefined" I have some questions around this code and the directive I'm trying to build:

  1. Why scope.states get "undefined" when JSON come with values?
  2. How do I access other select element selected option in order to get "cities"?

Note: app is a Angular module I have defined

EDIT

I rewrite some code and now this is the directive:

app.directive('country', ['$http', function($http) {
        return {
            restrict: 'C',
            link: function($scope, element, attrs) {
                element.change(function() {
                    $http.get(Routing.generate('states') + '/' + element.val()).success(function(data) {
                        if (data.message) {
                            $scope.message = data.message;
                        } else {
                            $scope.states = data;
                        }
                    }).error(function(data, status, headers, config) {
                        if (status == '500') {
                            $scope.message = "No hay conexión con el servidor.";
                        }
                    });
                });
            }
        }
    }]);

Im my template I have this HTML:

<select 
     id="common_commonbundle_standard_address_state" 
     ng-model="common_commonbundle_standard_address.state" 
     required="required" 
     ng-disabled="!states" 
     ng-options="state.name for state in states.entities" 
     tooltip="Estado" 
     tooltip-trigger="focus" 
     tooltip-placement="right" 
     wv-def="Estado" 
     wv-cur="" 
     wv-err="Error!" 
     wv-req="The value you selected is not a valid choice" 
     type="text" 
     class="state ng-scope ng-pristine ng-invalid ng-invalid-required"         
     var="common_commonbundle_standard_address.country" 
     disabled="disabled">
</select>

Why, if I do this $scope.states = data and it has values, the select isn't enabled and isn't populated with values?

10
  • 2
    most likely your console.log executes before your success function is done. put the console.log inside the success/error functions. $http.get returns a promise. Commented Mar 6, 2014 at 16:16
  • @MatthewRygiel I made some changes and fix the code, can you take a look at my edit? Commented Mar 6, 2014 at 17:55
  • Can you put your code or plunker or similar service so I can see more of your code interactions? Commented Mar 6, 2014 at 19:10
  • Also have a look at this: jsfiddle.net/annavester/Zd6uX It's an example of what you are trying to do. Commented Mar 6, 2014 at 19:15
  • 1
    With directives you will need to have them be able to talk to each other. Also your directives will most likely need controllers inside of them. This video shows how to set up communication between your directives. Hopefully that will help. egghead.io/lessons/angularjs-directive-communication Commented Mar 6, 2014 at 19:26

1 Answer 1

1

like the comment alluded to, you need to move your console logging inside of your success callback. that's just the nature of asynchronous requests.

For 1)

  $http.get(Routing.generate('states') + '/' + element.val()).success(function(data) {
    console.log('success!');
    if (data.message) {
      scope.message = data.message;
    } else {
      scope.states = data;
    }
    console.log(scope.states);
    console.log(scope.message);
  }).error(function(data, status, headers, config) {
    if (status == '500') {
      scope.message = "No hay conexión con el servidor.";
    }
  });

For 2) You would want to use whatever is getting set to ng-model

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.