Ritesh Waghela
Ritesh Waghela

Reputation: 3727

Directive scope variables are undefined

I have written the following directive:

WeatherApp.directive('map', function () {

    return{
        restrict : 'A',
        link: function(scope, elem, attr) {
            var latitude = scope.lat;
            var longitude = scope.lon;
         var  mapOptions = {
             zoom: 8,
             center: new google.maps.LatLng(latitude, longitude)
         };

         console.log("latitude ="+latitude);
         console.log("longitude ="+longitude);
         map = new google.maps.Map(elem[0], mapOptions);
        }
    }

});

I am using this directive in my html as follows:

<div class="google-map" map=""></div>

There is a controller HomeCtrl which is parent of this directive. HomeCtrl uses WetherService to fetch the lat, lon and sets it to the scope variable, but in the directive the value of latitude and longitude is undefined. I think this is because directive is getting compiled before the controller executes and fetches weather data. How can I set the scope data inside the directive? Thanks.

Upvotes: 0

Views: 430

Answers (4)

Chandermani
Chandermani

Reputation: 42669

What you can do is to create a watch over the lat and long value and create the map only when they get assigned.

In your scope create a object location that gets assigned the value returned from service. $watch for this variable change in your directive code.

 link: function(scope, elem, attr) {
         scope.$watch("location", function(newValue,oldValue) {   
            if(newValue) {
              var  mapOptions = {
                zoom: 8,
                center: new google.maps.LatLng(newValue.lat, newValue.long)
              };
              map = new google.maps.Map(elem[0], mapOptions);
            }
        }
  }

The data returned from the service needs to be assigned to scope variable location. You extend this sample to use isolated scope, but still you would have to do a watch.

Upvotes: 1

Idkt
Idkt

Reputation: 2996

You have to change the directive:

<div class="google-map" map lat="lat" lon="lon"></div>

And the directive declaration should contain scope;

WeatherApp.directive('map', function () {

return{
    scope: {
        lat: '@', // or '='
        lon: '@', // or '='
    },
    restrict : 'A',
    link: function(scope, elem, attr) {
        var latitude = scope.lat;
        var longitude = scope.lon;
     var  mapOptions = {
         zoom: 8,
         center: new google.maps.LatLng(latitude, longitude)
     };

     console.log("latitude ="+latitude);
     console.log("longitude ="+longitude);
     map = new google.maps.Map(elem[0], mapOptions);
    }
}

});

Upvotes: 1

Shivaraj
Shivaraj

Reputation: 613

You can put lat and lon on $watch.

Upvotes: 0

link
link

Reputation: 1676

What I would do is move the weather data retrieval to a service. Inject the service in your directive and set the lat and lon scope variables in a callback or after the promise of your data is fulfilled (depending on how you implemented the data retrieval).

Upvotes: 0

Related Questions