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 as undefined
while scope
logs fine as an Scope and even has a walks
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.
Best Answer
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 functionscope.walks
will be empty/undefined. Since your directive template contains{{}}
s, Angular sets up a$watch
onwalks
, 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:In your production code, just guard against it being undefined:
Update: If you are using a version of Angular where
$resource
supports promises, see also @sawe's answer.