1

I have the following in a controller:

 Restangular.all('foos').getList().then(
 function(foos) {
 $scope.foos = foos;
 });

In an HTML page, I am able to do the following:

<div ng-repeat="foo in foos | orderBy:'fooName'">

I want to move the ng-repeat to a directive, so I have the following in a directive:

app.directive('interactionFoos', function(){
return {
 restrict: 'A',
 scope : false,
 link: function($scope, $element, $attrs) {
 //console.log("*** size: " + $scope.foos.length);
 }
}
});

And in the HTML I will have:

<div interaction-foos></div>

In the directive, I am getting undefined for $scope.foos. As a test, in the controller, I hard coded: $scope.test= 'foobar'. Then, in the directive, I replaced the log line with the following and it printed 'foobar':

console.log("*** test: " + $scope.test);

I do not know why $scope.test is working as I expect, but $scope.foos is not?

asked Sep 25, 2014 at 20:12
3
  • 3
    Async issue? i.e. The link happening prior to the foo being set so it would error out and not re-run Commented Sep 25, 2014 at 20:18
  • What @ShawnC. said ... In the directive, try $scope.$watch('foos', function(newValue, oldValue) { console.log(newValue, oldValue); }); You don't necessarily need to use $watch in your solution, to avoid that you can assign $scope.foos to an empty array in the controller's "startup" code. Commented Sep 25, 2014 at 20:22
  • 1
    I'd post that as an answer, but I don't like to steal people's thunder. If you find it helps, maybe you can ask Shawn C. to do so :) Commented Sep 25, 2014 at 20:24

2 Answers 2

1

I believe this is an Async issue as Restangular would run as a promise so foo would not be set when the directive link function runs. To get around this you need to add a watch to see when the scope has changed

$scope.$watch('foos', function(newValue, oldValue) { console.log(newValue, oldValue); });

answered Sep 25, 2014 at 20:41
Sign up to request clarification or add additional context in comments.

Comments

0

do something like this:

angular.module("app", [])
.controller("interactionCtrl", function($scope) {
 $scope.foos = ["A", "B", "C"];
 })
.directive("interactionFoos", function() {
 return {
 restrict: 'A',
 scope: {
 foos: '='
 },
 link: function(scope, element, attrs) {
 alert(scope.foos.length);
 }
 };
});
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js"></script>
<div ng-app="app" ng-controller="interactionCtrl">
 <div interaction-foos foos="foos"></div>
</div>

basically the foos in the directive binds to the foos that are exposed on the controller.

also in your linking function don't use $ in the name of the function arguments, for example call the first argument scope instead of scope, because those arguments are not really injected to the link function (it's a regular function call, if you name the first argument bob it will still be equal to the scope)

answered Sep 25, 2014 at 20:33

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.