web-dev-qa-db-fra.com

Angularjs $ resource ne fonctionnant pas avec un tableau retourné par un REST API

J'essaie d'apprendre angularjs et je me suis heurté à un blocage en tentant de créer un databind dans un tableau renvoyé par une API Rest. J'ai un simple api Azure renvoyant un tableau d'objets personne. L'URL du service est http://testv1.cloudapp.net/test.svc/persons

Mon code de contrôleur ressemble à: 

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";
}

Mon html ressemble à:

<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: La table en HTML ci-dessus n’affiche aucune donnée. Je peux voir l'appel de l'API dans Firebug, ainsi que la réponse JSON de l'API. Qu'est-ce que je fais de manière incorrecte qui empêche la liaison de données avec l'API REST de fonctionner?

PS: JSFiddle présente ce problème à l’adresse: http://jsfiddle.net/jbliss1234/FBLFK/4/

14
John Bliss

Afin de gérer les tableaux avec le service $ resource, il est suggéré d'utiliser la méthode de requête. Comme vous pouvez le voir ci-dessous, la méthode de requête est conçue pour gérer les tableaux.

{ 'get':    {method:'GET'},
  'save':   {method:'POST'},
  'query':  {method:'GET', isArray:true},
  'remove': {method:'DELETE'},
  'delete': {method:'DELETE'} };

Le code que vous devez utiliser pour renvoyer ce tableau à votre portée est 

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";
}

Cela suppose que votre API REST fonctionne et renverra un tableau. 

Pour en savoir plus, allez à la documentation

http://docs.angularjs.org/api/ngResource.$resource

28
Gwash3189

Je voulais juste échanger mon adaptation d'une solution Aleksander a donné sur une autre question de stackoverflow: https://stackoverflow.com/a/16387288/626810 :

methodName: {method:'GET', url: "/some/location/returning/array", transformResponse: function (data) {return {list: angular.fromJson(data)} }}

Alors, quand j'appelle cette fonction:

var tempData = ResourceName.methodName(function(){
  console.log(tempData.list); // list will be the array in the expected format
});

Évidemment, ceci est un peu volumineux si vous devez obtenir des tableaux de plusieurs méthodes/ressources, mais cela semble fonctionner.

10
Blaskovicz

Utilisez isArray param, si vous avez des objets imbriqués:

angular.module('privilegeService', ['ngResource']).
factory('Privilege', function ($resource) {
    return $resource('api/users/:userId/privileges', 
                     {userId: '@id'}, 
                     {'query':  {method:'GET', isArray:false}});
});

Ensuite, vous pouvez utiliser la notation container.object.property pour accéder aux objets et à leurs propriétés.

6
Fanda

Je ne sais pas si nous avons le même problème avec JSON et REST, mais cet article a résolu mon problème: le tableau de chaînes non rendu correctement par le biais d'une ressource angulaire

0
Tony Z

Le tableau que vous récupérez du serveur n'est pas un tableau clair, mais présente des propriétés supplémentaires. Cela permet à ng-repeat de ne rien afficher lorsque vous le parcourez avec in.

Vous avez besoin d'un itérateur spécial pour parcourir le tableau à partir du serveur, ce qui ignorera ces propriétés supplémentaires. Donc, extrayez d'abord les données du tableau avec forEach, comme ceci:

$scope.items = []
var response = $scope.svc.get();
angular.forEach(response, function(item) {
  $scope.items.Push(item);
});

Alors tu peux faire

<tr ng-repeat="item in items">
0
Magne

J'ai eu le même problème et aucune des réponses n'a assez fonctionné pour moi, voici ce que j'ai fait:

    $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 + '}'))};
            }
        }
   });

Utilise jquery. En gros, convertissez un tableau en objet afin que la ressource angularjs ne fasse pas caca.

0
Brayden Hancock