Why is my $watch showing an array that appears to be empty?

I'm working on creating an AngularJS directive in order to use D3 to render a visualization, but I'm running into problems when it comes to setting a $watch. The majority of my stuff looks extremely similar to the AngularJS tutorial. My resources are configured in a file called resources.json, which I'm sure is returning correctly.

Here's the relevant code of what I have so far:

app.js

var resourceApp = angular.module("resourceApp", [
    'ngRoute',
    'resourceControllers',
    'resourceDirectives',
    'resourceServices'
]);

/* ... routing config ... */

controllers.js

var resourceControllers = angular.module('resourceControllers', []);

resourceControllers.controller("OverviewCtrl", [ '$scope', 'Resource',
    function($scope, Resource) {
        $scope.resources = Resource.query();
    }
]);

/* ... other controllers ... */

directives.js

var resourceDirectives = angular.module('resourceDirectives', []);

resourceDirectives.directive("resourceVisualization", function() {
   return {
      restrict: 'E',
      scope: {
          resources: '='
      },
      link: function(scope, el, attrs) {
          // svg setup is here

          scope.$watch("resources", function(nRes, oRes) {
              if (nRes) {
                 // this logs an array of Resource objects 
                 //(once expanded in Firebug)
                 console.log(nRes);

                 var cats = nRes.map(function(r) { return r.category; });
                 // this logs an empty array
                 console.log(cats);
               }
           });
      }
   };
 });

overview.html

<ul>
   <li ng-repeat="resource in resources">
      {{resource.name}}
   </li>
</ul>
<resource-visualization resources="resources"></resource-visualization>

resources.json (which is what services.js is configured to pull from)

[
 {
   "id": 1,
   "category": "test",
   "type": "sample",
   "name": "Test1"
 },
 {
   "id": 2,
   "category": "test",
   "type": "sample4",
   "name": "Test2"
 },
 {
   "id": 3,
   "category": "fake",
   "type": "sample1",
   "name": "Test3"
 },
 {
   "id": 4,
   "category": "new",
   "type": "sample2",
   "name": "Test4"
 }]

Now, I know that the REST call is working, because the <ul> is populated. However, in the directive, the logging statements are returning empty arrays. I'm aware of the the async-ness of $resource, but the object that is logged first in the $watch contains $resolved: true.

Am I missing something?

Answers


It's all fine. Your call to Resource.query() returns immediately an empty array. If the ajax call returns the real data, your array will be filled with the arrived data. So the first assignment to $scope.resources fires your $watch function with an empty array. You my solve your problem if you are using the $watchCollection function. See http://docs.angularjs.org/api/ng.$rootScope.Scope for further information.


Need Your Help

Choppy frame rate using a SourceDataLine

java swing repaint javasound frame-rate

I've been programming sound with simple Swing graphics for a little while, but my frame rates are choppy for some reason.