I'm getting TypeError: Cannot call method 'slice' of undefined when loading data from factory ng-Table AngularJS
Asked Answered
C

1

6

I'm new to AngularJS and got stucked in displaying the data when using ng-Table coming from a service. I'm getting an error

TypeError: Cannot call method 'slice' of undefined at Object.$scope.tableParams.ngTableParams.getData (index.html:122:32)

When i hard-coded the json data values it work just fine. I think the data from the factory contained more than just the json data result hence the problem with the slicing.

My controller looks like this:

myApp.controller('usersCtrl', function usersCtrl($scope, userData, $filter, ngTableParams, $log){

    userData.getUsers(function(users){
        $scope.users = users;
    })

    var users = $scope.users;

    $scope.$watch("filter.$", function () {
        $scope.tableParams.reload();
    });

    $scope.tableParams = new ngTableParams({
        page: 1,            // show first page
        count: 10,          // count per page
        sorting: {
            name: 'asc'     // initial sorting
        }
    }, {
        getData: function($defer, params) {
            var filteredData = $filter('filter')(users, $scope.filter);
            var orderedData = params.sorting() ?
                                $filter('orderBy')(filteredData, params.orderBy()) :
                                filteredData;

            $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
        },
        $scope: $scope
    });

});

Then my factory service is this:

myApp.factory('userData', function($http, $log){
    return {
        getUsers: function(successcb){
            $http({method: 'GET', url: 'api/users'}).
                success(function(data, status, headers, config){
                    successcb(data);
                    $log.warn(data, status, headers, config);
                }).
                error(function(data, status, headers, config){
                    $log.warn(data, status, headers, config);
                });
        }
    }
});

My HTML is this :

<div class="row">
    <div>
        <p>Filter: <input class="form-control" type="text" ng-model="filter.$" /></p>

        <table ng-table="tableParams" class="table">
            <tr ng-repeat="user in $data">
                <td data-title="'Name'" sortable="name">
                    {{user.name}}
                </td>
                <td data-title="'Age'" sortable="'age'">
                    {{user.age}}
                </td>
            </tr>
        </table>
    </div>
</div>
Capon answered 21/11, 2013 at 7:38 Comment(0)
E
4

You need to resolve $defer within table getData after the ajax has completed. As it stands right now if you were to log filteredData to console, it will be undefined, thus it can't be sliced.

Try moving userData.getUsers to:

getData: function ($defer, params) {
     /* make ajax call */
    userData.getUsers(function(users) {
        /* now we have data to work with*/
        $scope.users = users;

        var filteredData = $filter('filter')(users, $scope.filter);
        var orderedData = params.sorting() ? $filter('orderBy')(filteredData, params.orderBy()) : filteredData;
        /* and can resolve table promise  */
        $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));

    })

}
Evolutionary answered 21/11, 2013 at 8:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.