0

Using angular-seed project: In directives.js

var names = [];
Animals.query(function(data){ // Animals.query() from service.js
  console.log(data.Names); // output > [Object, Object..., Object]  
  names = data.Names; // attempt to bind to outer variable
});
console.log(names); // output > []

I can see the data there but I need it outside the function. How do I get it outside the function? console.log(names); happens before console.log(data.Names); I know it has to do with closures and maybe callbacks and I've tried many things and but I can't seem to get them to work for my case. I end up with an ever expanding mess of functions wrapped in callbacks wrapped in functions with still no binding to outside variable. I don't want to 'pollute the global namespace' but I need ahold of the data outside the inner function. The end-purpose is to get the data to be available for d3.js processing. There must be a simpler way. Can someone please help me with this particular case?

3
  • 1
    If you need to share the same data with several components, put it in a service. Commented Jul 19, 2013 at 19:02
  • 1
    ah from rereading your question itself you should be able to inject the service into the directive to get the data (or setup a watch to watch the service and update the directive). I think the more "proper" way to go would be to have the controller setup scope variables that are passed into the directives but I may be wrong Commented Jul 19, 2013 at 20:26
  • Yes, to both of the above and comments. I misunderstood where and how data should be loaded with respect to directives- I see now that as Paulo said the data should come from a service outside the directive and passed to the directive via a controller as shaunhusain says, and used the way Joe describes below. Also, I believe now that route-providers makes it possible for the directive to not fire until the service is finished and triggers the controller. I hope to update this when I get a proper example working. Commented Jul 29, 2013 at 18:48

1 Answer 1

1

Hope I'm not misunderstanding you: you've already created (I assume) a function Animals as a service. Why don't you inject that in the controller of the directive's scope?

as in :

function Controller($scope, Animals){
  $scope.names = [];
  $scope.updateD3viz = function(){
    // do your d3 stuff here
    $scope.names = Animals.query(); // or whatever
  }
}

$scope will be accessible from the directive's link(scope,elem,attrs) method.

I had to do something similar (angular and d3) and i ended up having a d3 graph as a controller's scope property to make sure it was included in angular's lifecycle.

3
  • Thanks, that just might work! - I was able to bind to $scope.xxx in another area but for some reason can't get it to bind to something separate outside the function. And looking at your approach now - I think I've gotten tunnel vision on solving this problem, and your answer may have helped dislodge my thinking. As soon as I get a chance to work on it again, I'll check off your answer :) Commented Jul 19, 2013 at 22:05
  • Yes, thank you - right or wrong, I did give up trying to get the data modeled outside of the functions scope and modeled it inside the scope. Commented Jul 22, 2013 at 12:39
  • Update: although it works, my approach above is not the 'proper' way to do it. The way I'm doing it now, as you describe above, is put the external query into a service, which the route provider waits on and when the data is ready passes it to the controller which then the directive can pass on to the d3.js processing inside it. I said a bunch of words like a parrot does, but don't know what I'm talking about :) Commented Jul 29, 2013 at 18:56

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.