预期的数组但收到...(JSON)... AngularJS错误

Posted

技术标签:

【中文标题】预期的数组但收到...(JSON)... AngularJS错误【英文标题】:Expected Array but received ...(JSON)... AngularJS Error 【发布时间】:2017-05-09 23:37:45 【问题描述】:

我正在从 Adam Freeman 的 ,,Pro AngularJS" 书中学习 Angular1。我在构建他在第 6-8 章中描述的 DeployD 应用程序时遇到了问题 - 我的代码似乎不想阅读 JSON

这是我的 html

<!DOCTYPE html>
<html ng-app="sportsStore" lang="pl">
<head>
    <title>SportsStore</title>
    <script src="components/angular.js"></script>
    <script src="components/angular-resource.js"></script>
    <link href="components/bootstrap.css" rel="stylesheet" />
    <link href="components/bootstrap-theme.css" rel="stylesheet" />
    <script>
        angular.module("sportsStore", ["customFilters"]);
    </script>
    <script src="controllers/sportsStore.js"></script>
    <script src="filters/customFilters.js"></script>
    <script src="controllers/productListControllers.js"></script>
</head>
<body ng-controller="sportsStoreCtrl">
<div class="navbar navbar-inverse">
    <a class="navbar-brand" href="#">SKLEP SPORTOWY</a>
</div>
<div class="panel panel-default row" ng-controller="productListCtrl">
    <div class="alert alert-danger" ng-show="data.error">
        Błąd (data.error.status). Dane produktu nie zostały wczytane.
        <a href="/index.html" class="alert-link">Kliknij tutaj, aby spróbować ponownie</a>
    </div>
    <div class="panel panel-default row" ng-controller="productListCtrl"
         ng-hide="data.error">
    <div class="col-xs-3">
        <a ng-click="selectCategory()"
           class="btn btn-block btn-default btn-lg">Strona główna</a>
        <a ng-repeat="item in data.products | orderBy:'category' |
unique:'category'" ng-click="selectCategory(item)" class=" btn btn-block
btn-default btn-lg" ng-class="getCategoryClass(item)">
            item
        </a>
    </div>
    <div class="col-xs-8">
        <div class="well"
             ng-repeat="item in data.products | filter:categoryFilterFn |
range:selectedPage:pageSize">
            <h3>
                <strong>item.name</strong>
                <span class="pull-right label label-primary">
item.price | currency
</span>
            </h3>
            <span class="lead">item.description</span>
        </div>
        <div class="pull-right btn-group">
            <a ng-repeat="page in data.products | filter:categoryFilterFn |
                    pageCount:pageSize" ng-click="selectPage($index + 1)" class="btn
btn-default" ng-class="getPageClass($index + 1)">
                $index + 1
            </a>
        </div>
    </div>
</div>
</body>
</html>

和 sportStore.js 控制器

angular.module("sportsStore")
    .constant("dataUrl", "http://localhost:5500/products")
    .controller("sportsStoreCtrl", function ($scope, $http, dataUrl) 
        $scope.data = ;
        $http.get(dataUrl)
            .then(function (data) 
                $scope.data.products = data;
            ,
            function (error) 
                $scope.data.error = error;
            );
    );

我正在使用 DeployD 构建 API,问题是当我尝试运行我的应用程序时,控制台中显示错误:

错误:[filter:notarray] 预期的数组但已收到: "data":["name":"Kajak","description":"Łódka przeznaczona dla jednej osoby","类别":"运动型 Wodne","price":275,"id":"d9b9e4fcb9df3853","name":"Kamizelka ratunkowa","description":"Chroni i dodaje uroku","category":"Sporty wodne","price":49.75,"id":"3c1cceedb44ddb84","name":"Piłka","description":"Zatwierdzona przez FIFA rozmiar i waga","类别":"Piłka Nożna","price":19.5,"id":"447a2079a8488932","name":"Flagi narożne","description":"Nadadzą Twojemu boisku profesjonalny wygląd","类别":"Piłka Nożna","price":34.95,"id":"2b2dd597f18bb8a7","name":"Stadion","description":"Składany 体育场 na 35000 osób","类别":"Piłka Nożna","price":79500,"id":"2cfe0f6767240bf9","name":"Czapka","description":"Zwiększa efektywność mózgu o 75%","category":"Szachy","price":16,"id":"dfc137db43574b4a","name":"Niestabilne krzesło","description":"Zmniejsza szansę przeciwnika","category":"Szachy","price":29,"id":"e2b644c5091d28ca","name":"Ludzka szachownica","description":"Przyjemna gra dla całej rodziny","category":"Szachy","price":75,"id":"f945806bb011895d","name":"Błyszczący król","description":"Pokryty złotem i wysadzany diamentami król","category":"Szachy","price":1200,"id":"fab242704bb38b64"],"status":200,"config":"method":"GET","transformRequest": [null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"http://localhost:5500/products","headers":"Accept":"application/json, 文本/纯文本,/","statusText":"OK" http://errors.angularjs.org/1.6.0-rc.1/filter/notarray?p0=%7B%22data%22%3A%…son%2C%20text%2Fplain%2C%20*%2F*%22%7D%7D%2C%22statusText%22%3A%22OK%22%7D 在 angular.js:68 在 angular.js:20392 在 fn(编译时的评估(angular.js:15095),:4:388) 在 regularInterceptedExpression (angular.js:16203) 在 Scope.$digest (angular.js:17732) 在 Scope.$apply (angular.js:18006) 完成后(angular.js:12150) 在 completeRequest (angular.js:12376) 在 XMLHttpRequest.requestLoaded (angular.js:12304)

我试图略过 SO 上的类似错误,但似乎没有一个解决方案适合我。有人有类似的问题吗?

【问题讨论】:

$httpthen() 中的响应对象不是数据本身...它有一个属性 data 这就是您所需要的 【参考方案1】:

ng repeat 与数组一起使用,但根据then() 方法中从 API 获得的响应不是数据本身,但它有一个名为 data 的属性,这是您必须传递的实际数组在ng-repeat

所以,不要使用$scope.data.products = data,而是使用$scope.data.products = data.data

----------OR----------

.then(function (response) 
  $scope.data.products = response.data;

        

【讨论】:

【参考方案2】:

错误消息显示过滤器拒绝处理响应对象而不是数据数组。 Expected array but received: data:[..., headers: ...

$http 服务的.then 方法返回一个响应对象,而不是数据。

angular.module("sportsStore")
    .constant("dataUrl", "http://localhost:5500/products")
    .controller("sportsStoreCtrl", function ($scope, $http, dataUrl) 
        $scope.data = ;
        $http.get(dataUrl)
            //.then(function (data) 
            //    $scope.data.products = data;
            .then(function (response) 
                $scope.data.products = response.data;
            ,
            function (error) 
                $scope.data.error = error;
            );
    );

数据只是响应对象的一个​​属性:

$http(...).
  then(function onSuccess(response) 
    // Handle success
    var data = response.data;
    var status = response.status;
    var statusText = response.statusText;
    var headers = response.headers;
    var config = response.config;
    ...
  , function onError(response) 
    // Handle error
    var data = response.data;
    var status = response.status;
    var statusText = response.statusText;
    var headers = response.headers;
    var config = response.config;
    ...
  );

【讨论】:

【参考方案3】:

ng 重复和过滤适用于数组,您需要访问 数据

 angular.module("sportsStore")
    .constant("dataUrl", "http://localhost:5500/products")
    .controller("sportsStoreCtrl", function ($scope, $http, dataUrl) 
        $scope.data = ;
        $http.get(dataUrl)
            .then(function (data) 
                $scope.data.products = data.data;
            ,
            function (error) 
                $scope.data.error = error;
            );
    );

【讨论】:

【参考方案4】:

Angular 期望数据变量是数组类型。

$scope.data =  [];

然后试试下面的代码:

$http.get('dataUrl')
    .success(function(data) 
        $scope.data = data;
    ).error(function(data, status) 
        $log.error('Error ' + status + ' unable to get data from server.');
);

还记得将$log 添加到您的控制器中以在控制台中正确显示错误:

.controller('sportsStoreCtrl', ['$scope', '$http', '$log', function ($scope, $http, $log)

【讨论】:

以上是关于预期的数组但收到...(JSON)... AngularJS错误的主要内容,如果未能解决你的问题,请参考以下文章

解析 JSON 错误“预期解码 Array<Any> 但找到了一个数字

使用无效键值访问的 JArray 值:“字段”。预期数组位置索引

预期解码 Dictionary<String, Any> 但找到一个数组而不是 JSON SwiftUI

资源配置错误。包含对象但得到数组的预期响应

包含对象但得到数组的预期响应

JsonReader - 读取数组抛出预期名称但为 NULL