Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angularjs passing object to directive

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.

like image 376
winkerVSbecks Avatar asked Jan 31 '13 06:01

winkerVSbecks


People also ask

What is attrs in AngularJS?

scope is an AngularJS scope object. element is the jqLite-wrapped element that this directive matches. attrs is a hash object with key-value pairs of normalized attribute names and their corresponding attribute values. controller is the directive's required controller instance(s) or its own controller (if any).

What is restrict in AngularJS directive?

Restrict. Angular allows us to set a property named restrict on the object we return on our directive definition. We can pass through a string with certain letters letting Angular know how our directive can be used. function MyDirective() { return { restrict: 'E', template: '<div>Hello world!

What is restrict option in directive?

Directive comes with many Directive Definition Objects (DDO). From them restrict is one. Using restrict option inside a Custom Directive we can prevent the access level of Directive for Element(E), Attribute(A), Comment(M) or Class(C).


2 Answers

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.

like image 74
Mark Rajcok Avatar answered Oct 16 '22 13:10

Mark Rajcok


you may also use

scope.walks.$promise.then(function(walks) {     if(walks) {       console.log(walks);     }   }); 
like image 36
sawe Avatar answered Oct 16 '22 13:10

sawe