Reputation: 429
I am trying to learn angularjs, and have hit a block in trying to databind to an array returned from a Rest API. I have a simple azure api returning an array of person objects. Service url is http://testv1.cloudapp.net/test.svc/persons.
My controller code looks like:
angular.module("ToDoApp", ["ngResource"]);
function TodoCtrl($scope, $resource) {
$scope.svc = $resource('http://testv1.cloudapp.net/test.svc/persons', {
callback: 'JSON_CALLBACK'
}, {
get: {
method: 'JSONP',
isArray: true
}
});
$scope.items = $scope.svc.get();
$scope.msg = "Hello World";
}
My html looks like:
<html>
<head></head>
<body>
<div ng-app="ToDoApp">
<div ng-controller="TodoCtrl">
<h1>{{msg}}</h1>
<table class="table table-striped table-condensed table-hover">
<thead>
<th>Email</th>
<th>First Name</th>
<th>Last Name</th>
</thead>
<tbody>
<tr ng-repeat="item in items">
<td>{{item.Email}}</td>
<td>{{item.FirstName}}</td>
<td>{{item.LastName}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
Question: The table in above html is not displaying any data. I can see the call to the api in Firebug, and can also see the JSON response from the api. What am I doing incorrectly that is causing the databinding to the REST api not work?
PS:JSFiddle demonstrating this issue is at: http://jsfiddle.net/jbliss1234/FBLFK/4/
Upvotes: 14
Views: 48362
Reputation: 796
I had similar problem and non of the answers quite worked for me, heres what i did:
$resource("/", {}, {
query: {
method: 'GET',
isArray: false,
transformResponse: function (data, headers) {
//if no data return so no warnings
if (data == ''){
return;
}
return {data: $.extend({}, eval("{" + data + '}'))};
}
}
});
Uses jquery. Basically convert array to object so angularjs resource doesn't poop its pants.
Upvotes: 0
Reputation: 17223
The array you get back from the server isn't a clean array, but has some extra properties. That makes ng-repeat
not show anything when you iterate over it using in
.
You need a special iterator to go over the array from the server, which will ignore those extra properties. So extract the array data through forEach
first, like this:
$scope.items = []
var response = $scope.svc.get();
angular.forEach(response, function(item) {
$scope.items.push(item);
});
Then you can do
<tr ng-repeat="item in items">
Upvotes: 0
Reputation: 6160
Just wanted to cross-post my adaptation of a solution Aleksander gave on another stackoverflow question: https://stackoverflow.com/a/16387288/626810:
methodName: {method:'GET', url: "/some/location/returning/array", transformResponse: function (data) {return {list: angular.fromJson(data)} }}
So when I call this function:
var tempData = ResourceName.methodName(function(){
console.log(tempData.list); // list will be the array in the expected format
});
Obviously this a little bulky if you need to GET arrays in multiple methods / resources, but it seems to work.
Upvotes: 11
Reputation: 194
Not sure if we are having the same problem with json and REST, but this post solved my problem: array of strings not rendered correctly through angular resource
Upvotes: 0
Reputation: 333
In order to handle arrays with the $resource service, it's suggested that you use the query method. As you can see below, the query method is built to handle arrays.
{ 'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'} };
The code you should use in order to return this array to your scope is
angular.module("ToDoApp", ["ngResource"]);
function TodoCtrl($scope, $resource) {
var svc = $resource('http://testv1.cloudapp.net/test.svc/persons');
$scope.items = svc.query();
$scope.msg = "Hello World";
}
This assumes that your REST API is working and will return an array.
For further reading head to the docs
http://docs.angularjs.org/api/ngResource.$resource
Upvotes: 29
Reputation: 3786
Use isArray param, if you have nested objects:
angular.module('privilegeService', ['ngResource']).
factory('Privilege', function ($resource) {
return $resource('api/users/:userId/privileges',
{userId: '@id'},
{'query': {method:'GET', isArray:false}});
});
Than you can use container.object.property
notation to access objects and its properties.
Upvotes: 7