web-dev-qa-db-fra.com

Angularjs Erreur: [filtre: notarray] Tableau attendu mais reçu: {} avec un filtre sur une répétition de ng

Je tente de renseigner une table HTML à l'aide d'une requête angulaire adressée à une API à l'aide de la directive ng-repeat. La page html se charge en premier puis la demande est faite pour obtenir les données qui remplissent la table lorsque la réponse est renvoyée . Lorsque j'ajoute un filtre à la directive ng-repeat, la table est remplie et les fonctions de filtre console de navigateur chrome je reçois l'erreur suivante:

Erreur: [filtre: notarray] Tableau attendu mais reçu: {} http://errors.angularjs.org/1.4.3/filter/notarray?p0=%7B%7D sur REGEX_STRING_REGEXP (angular.js: 68) à angular.js: 18251 sur Object.fn (app.js: 185) à la portée. $ get.Scope. $ digest (angular.js: 15683) à la portée. $ get.Scope. $ apply (angular.js: 15951) at bootstrapApply (angular.js: 1633) sur Object.invoke (angular.js: 4450) at doBootstrap (angular.js: 1631) au démarrage (angular.js: 1651) at angularInit (angular.js: 1545)

J'ai installé un échantillon sur plunker, l'erreur est également affichée dans la console ici lorsque l'échantillon est exécuté:

http://plnkr.co/edit/J83gVsk2qZ0nCgKIKynj ?

Le html:

<!DOCTYPE html>
<html>
<head>
  <script data-require="angular.js@*" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular.js"></script>
  <script data-require="angular-route@*" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular-route.js"></script>
  <script data-require="angular-resource@*" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular-resource.js"></script>
  <script type="text/javascript" src="example.js"></script>
  <link href="//netdna.bootstrapcdn.com/Twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css" rel="stylesheet" />
</head>
<body ng-app="inventoryManagerApp">
  <h3>Sample - Expected array error</h3> Filter
  <input type="text" id="quoteListFilter" class="form-control" ng-  model="search" />
  <div ng-controller="QuoteController">
    <table class="table table-bordered">
      <tbody>
        <tr>
          <th>Specification</th>
          <th>Quantity</th>
        </tr>
        <tr ng-repeat="quote in quotes | filter:search">
          <td>{{quote.SpecificationDetails}}</td>
          <td>{{quote.Quantity}}</td>
        </tr>
      </tbody>
    </table>
  </div>
</body>
</html>

Le javascript:

var inventoryManagerApp = angular.module('inventoryManagerApp', [
  'ngResource',
  'quoteControllers'
]);

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

quoteControllers.controller("QuoteController", ['$scope', 'filterFilter', 'quoteRepository',
  function($scope, filterFilter, quoteRepository) {

     $scope.quotes = quoteRepository.getQuoteList().$promise.then(
            function (result) {
                $scope.quotes = result;
            },
            function () {
            }
        );
  }
]);

inventoryManagerApp.factory('quoteRepository',
  function($resource) {
    return {
      getQuoteList: function() {
        return    $resource('http://drbsample.azurewebsites.net/api/Quotes').query();
      }
    };
  });

Il semble que les données servant à remplir la directive ng-repeat ne soient pas immédiatement disponibles au chargement de la page. Lorsque je remplace les $ scope.quotes par les données JSON lors du chargement de la page au lieu de demander des données à l'API, l'erreur ne s'affiche pas.

12
stonefree

Le problème est avec cette affectation:

$scope.quotes = quoteRepository.getQuoteList().$promise.then(
        function (result) {
            $scope.quotes = result;
        },
        function () {
        }
    );

La fonction .then() renvoie un autre objet de promesse pour permettre l'enchaînement: .then().then(), et parce qu'elle renvoie un objet, c'est pourquoi vous recevez une erreur notarray.

Pour éviter les erreurs de référence, vous pouvez spécifier $scope.quotes plus tôt comme tableau vide, puis lui attribuer les résultats.

$scope.quotes = [];
quoteRepository.getQuoteList().$promise.then(
        function (result) {
            $scope.quotes = result;
        },
        function () {
        }
    );
25
Mateusz Kmiecik
$scope.quotes = quoteRepository.getQuoteList().$promise.then(

la mission est inutile. supprimez simplement le $scope.quotes = de la ligne a résoudre votre problème.

promise.then retourne alors un objet qui est inutile pour une déclaration répétée.

7
ibrahimbayer
quoteRepository.getQuoteList().then(
    function (result) {
        $scope.quotes = result;
    },
    function () {
    }
);
0
Rafael Francisco

Les méthodes de promesse héritées $ http .success et .error sont obsolètes et seront supprimées dans Angular v1.6.0. Utilisez plutôt la méthode standard .then.

Maintenant, la méthode .then retourne un objet avec plusieurs éléments: données, statut, etc. Vous devez donc utiliser response.data au lieu de simplement response:

$http.get('https://example.org/...')
  .then(function (response) {

    console.log(response);

    var data = response.data;
    var status = response.status;
    var statusText = response.statusText;
    var headers = response.headers;
    var config = response.config;

    console.log(data);

});
0
Roman