I'm learning Angular1 from Adam Freeman's ,,Pro AngularJS" book. I've got a problem with building a DeployD app he's describing in chapters 6-8 - it seems like my code doesn't want to read JSON

That's my 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>

and the sportStore.js controller

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

I'm using DeployD to build an API, and the problem is that when I try to run my app, the error shows up in console:

Error: [filter:notarray] Expected array but received: {"data":[{"name":"Kajak","description":"Łódka przeznaczona dla jednej osoby","category":"Sporty 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","category":"Piłka Nożna","price":19.5,"id":"447a2079a8488932"},{"name":"Flagi narożne","description":"Nadadzą Twojemu boisku profesjonalny wygląd","category":"Piłka Nożna","price":34.95,"id":"2b2dd597f18bb8a7"},{"name":"Stadion","description":"Składany stadion na 35000 osób","category":"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, text/plain, /"}},"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 at angular.js:68 at angular.js:20392 at fn (eval at compile (angular.js:15095), :4:388) at regularInterceptedExpression (angular.js:16203) at Scope.$digest (angular.js:17732) at Scope.$apply (angular.js:18006) at done (angular.js:12150) at completeRequest (angular.js:12376) at XMLHttpRequest.requestLoaded (angular.js:12304)

I tried to skim through similar errors on SO but none of the solutions seemed to work for me. Did someone have a similar problem?

share|improve this question
    
The response object in then() of $http is not the data itself...it has a property data that is what you need – charlietfl Dec 24 '16 at 17:29

ng repeat and filter works with array, you need to access the data

 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;
            });
    });
share|improve this answer

ng repeat works with an arrays but as per the response getting from the API in then() method is not the data itself but it is having a property named as data which is the actual array that you have to pass in ng-repeat.

So, instead of using $scope.data.products = data use $scope.data.products = data.data

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

.then(function (response) {
  $scope.data.products = response.data;
}
share|improve this answer

Angular expects the data variable to be type of array.

$scope.data =  [];

Then try following code:

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

Also remember to add to your controller the $log to properly display bugs in console:

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

share|improve this answer

The error message shows the filter refusing to process the response object instead of the data array. Expected array but received: {data:[..., headers: ...

The .then method of the $http service returns a response object, not data.

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

Data is only one property of the response object:

$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;
    ...
  });
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.