skip to Main Content

I am attempting to populate an html table using an angular request to an API using the ng-repeat directive. The html page loads first then the request is made to get the data which fills the table when the response is returned.
When I add a filter to the ng-repeat directive the table is populated and the filter functions, however in my chrome browser console I get the following error:

Error: [filter:notarray] Expected array but received: {}
http://errors.angularjs.org/1.4.3/filter/notarray?p0=%7B%7D
at REGEX_STRING_REGEXP (angular.js:68)
at angular.js:18251
at Object.fn (app.js:185)
at Scope.$get.Scope.$digest (angular.js:15683)
at Scope.$get.Scope.$apply (angular.js:15951)
at bootstrapApply (angular.js:1633)
at Object.invoke (angular.js:4450)
at doBootstrap (angular.js:1631)
at bootstrap (angular.js:1651)
at angularInit (angular.js:1545)

I have set a sample up on plunker, the error is also displayed in the console here when the sample is run:

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

The 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>

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

It seems to be something to do with the data to fill the ng-repeat directive not being immediately available on page load. When I replace the $scope.quotes with the json data on page load instead of requesting data from the API do not get the error.

4

Answers


  1. $scope.quotes = quoteRepository.getQuoteList().$promise.then(
    

    the assignment is useless. just delete the $scope.quotes = from the line has to solve your problem.

    promise.then is returning an object which is useless for repeat statement.

    Login or Signup to reply.
  2. The problem is with this assignment:

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

    Function .then() returns another promise object to allow chaining: .then().then(), and because it returns an object that’s why your receive notarray error.

    To avoid reference error you can specify $scope.quotes as empty arrray earlier, then assign results to it.

    $scope.quotes = [];
    quoteRepository.getQuoteList().$promise.then(
            function (result) {
                $scope.quotes = result;
            },
            function () {
            }
        );
    
    Login or Signup to reply.
  3. The $http legacy promise methods .success and .error have been deprecated and will be removed in Angular v1.6.0. Use the standard .then method instead.

    Now .then method returns object with several elements: data, status, etc. So you need to use response.data instead of just 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);
    
    });
    
    Login or Signup to reply.
  4. quoteRepository.getQuoteList().then(
        function (result) {
            $scope.quotes = result;
        },
        function () {
        }
    );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search