Angularjs passing object to directive
Solution 1
Since you are using $resource
to obtain your data, the directive's link function is running before the data is available (because the results from $resource
are asynchronous), so the first time in the link function scope.walks
will be empty/undefined. Since your directive template contains {{}}
s, Angular sets up a $watch
on walks
, so when the $resource
populates the data, the $watch
triggers and the display updates. This also explains why you see the walks data in the console -- by the time you click the link to expand the scope, the data is populated.
To solve your issue, in your link function $watch
to know when the data is available:
scope.$watch('walks', function(walks) {
console.log(scope.walks, walks);
})
In your production code, just guard against it being undefined:
scope.$watch('walks', function(walks) {
if(walks) { ... }
})
Update: If you are using a version of Angular where $resource
supports promises, see also @sawe's answer.
Solution 2
you may also use
scope.walks.$promise.then(function(walks) {
if(walks) {
console.log(walks);
}
});
Solution 3
Another solution would be to add ControllerAs
to the directive by which you can access the directive's variables.
app.directive('walkmap', function() {
return {
restrict: 'A',
transclude: true,
controllerAs: 'dir',
scope: { walks: '=walkmap' },
template: '<div id="map_canvas"></div>',
link: function(scope, element, attrs)
{
console.log(scope);
console.log(scope.walks);
}
};
});
And then, in your view, pass the variable using the controllerAs
variable.
<div walkmap="store.walks" ng-init="dir.store.walks"></div>
Solution 4
Try:
<div walk-map="{{store.walks}}"></div>
angular.module('app').directive('walkMap', function($parse) {
return {
link: function(scope, el, attrs) {
console.log($parse(attrs.walkMap)(scope));
}
}
});
Comments
-
winkerVSbecks about 4 years
Angular newbie here. I am trying to figure out what's going wrong while passing objects to directives.
here's my directive:
app.directive('walkmap', function() { return { restrict: 'A', transclude: true, scope: { walks: '=walkmap' }, template: '<div id="map_canvas"></div>', link: function(scope, element, attrs) { console.log(scope); console.log(scope.walks); } }; });
and this is the template where I call the directive:
<div walkmap="store.walks"></div>
store.walks
is an array of objects.When I run this,
scope.walks
logs asundefined
whilescope
logs fine as an Scope and even has awalks
child with all the data that I am looking for.I am not sure what I am doing wrong here because this exact method has worked previously for me.
EDIT:
I've created a plunker with all the required code: http://plnkr.co/edit/uJCxrG
As you can see the
{{walks}}
is available in the scope but I need to access it in the link function where it is still logging as undefined.