Question

I am fetching a list of data from the backend and displaying it using ng-table. The problem is that its not showing the pagination controls. Previously, when I used dummy data to show the ng-table, pagination was working totally fine. Could someone help me out here?

This is my HTML:

<table ng-table="tableParams" show-filter="true" class="table">
            <thead>
                    <tr>
                            <th ng-repeat="column in columns" ng-show="column.visible"
                                    class="text-center" ng-class="{
                                    'sort-asc': tableParams.isSortBy(column.field, 'asc'),
                                    'sort-desc': tableParams.isSortBy(column.field, 'desc'),
                                    'sortable': !$first
                                    }"
                                    ng-click="tableParams.sorting(column.field, tableParams.isSortBy(column.field, 'asc') ? 'desc' : 'asc')">
                                    <div>{{column.title}}</div>
                            </th>
                    </tr>

            </thead>
            <tr ng-repeat="user in data | filter:searchText">

                    <td width="30" style="text-align: left">
                            <input type="checkbox" ng-model="checkboxes.items[user.id]" />
                    </td>

                    <td data-title="'Email Id'" class="text-center" sortable="email" ng-show="columns[1].visible">
                            <span>{{user.email}}</span>
                    </td>
                    <td data-title="'User Karma'" class="text-center" sortable="userkarma" ng-show="columns[2].visible">
                            <span>{{user.userkarma}}</span>
                    </td>
                    <td data-title="'Date Joined'" class="text-center" sortable="datejoined" ng-show="columns[3].visible">
                            <span>{{user.datejoined}}</span>
                    </td>
                    <td data-title="'Unsubscribed'" class="text-center" sortable="status" ng-show="columns[4].visible">
                            <span>{{user.unsubscribed}}</span>
                    </td>
            </tr>
        </table>

Below is my js file:

for (var i = 0; i < UserList.getUsers()
            .length; i++) {
            $scope.data.push({
                id: UserList.getUsers()[i]._id,
                email: UserList.getUsers()[i].email,
                userkarma: UserList.getUsers()[i].healthScore,
                datejoined: moment(UserList.getUsers()[i].firstSessionAt)
                    .format("MMMM Do YYYY"),
                unsubscribed: UserList.getUsers()[i].unsubscribed
            })
        };
        $scope.columns = [{
                title: '',
                field: 'checkbox',
                visible: true
            },
            {
                title: 'Email',
                field: 'email',
                visible: true
            }, {
                title: 'User Karma',
                field: 'userkarma',
                visible: true
            }, {
                title: 'Date Joined',
                field: 'datejoined',
                visible: true
            }, {
                title: 'Unsubscribed',
                field: 'unsubscribed',
                visible: true
            }
        ];

        $scope.tableParams = new ngTableParams({
            page: 1, 
                count: 10, // count per page
                filter: {
                    name: 'M' // initial filter
                },
                sorting: {
                    name: 'asc'
                }
            }, {
                total: $scope.data.length, // length of data
                getData: function ($defer, params) {
                    // use build-in angular filter
                    var filteredData = params.filter() ?
                        $filter('filter')($scope.data, params
                            .filter()) :
                        data;
                    var orderedData = params.sorting() ?
                        $filter('orderBy')($scope.data,
                            params.orderBy()) :
                        $scope.data;
                    params.total(orderedData.length); // set total for recalc paginationemail

                    $defer.resolve(orderedData.slice((
                            params.page() -
                            1) * params.count(),
                        params.page() *
                        params.count()));
                }
            });
Was it helpful?

Solution

This happens because the usual $scope.tableParams.reload() function used to refresh the data after an asynchronous data load does not refresh the total item count in the table. It didn't happen before because this value is correctly set at the beginning when you were using dummy data.

You need to add a params.total(data.length); the getData function to manually refresh the value.

OTHER TIPS

For me, it's because I was using coffeescript, which automatically returns the value of the last thing in your function. This causes problems because ng-table's getData() gets back a promise, and if it doesn't get one, it creates one itself, from $defer. By using coffeescript and not quite properly converting the example from the Configuring your table with ngTableParams wiki page, I was returning something that wasn't a promise.

In coffeescript, make sure your callback to getData() ends with either

$defer.promise

or

return

so that ng-table gets a promise, or knows to make one itself.

I found the answer. Actually there is an issue with ng-table when loading dynamic data. When the data is dynamically loaded, the getData function is not called. So this is what I did. I created a refreshTable function to call the setTable function which then calls the getData function and renders the table.

$scope.refreshTable = function () {
            console.log('\n\n refreshing table')
            $scope['tableParams'] = {
                reload: function () {},
                settings: function () {
                    return {}
                }
            };
            $timeout(setTable, 100)
        };
        $scope.refreshTable();

        function setTable(arguments) {

            $scope.tableParams = new ngTableParams({
                page: 1, // show first page
                count: 10, // count per page
                filter: {
                    name: '' // initial filter
                },
                sorting: {
                    name: 'asc'
                }
            }, {
                filterSwitch: true,
                total: $scope.users.length, // length of data
                getData: function ($defer, params) {
                    console.log(
                        '\n\nngTable getData called now')
                    var orderedData = params.sorting() ?
                        $filter('orderBy')($scope.users,
                            params.orderBy()) :
                        data;
                    params.total(orderedData.length);
                    $defer.resolve(orderedData.slice((params.page() -
                            1) * params.count(), params.page() *
                        params.count()));
                }
            });
        }

I had this problem and applied solution provided here but it not solved my problem.My usage was like below

    <table ng-table="tableParams" class="table  ng-table table-striped"  show-filter="{{::showFilter}}">
        <tr ng-show="showHeaders">
            <th class="th-select" ng-repeat="column in columns">{{column.title}}</th>
        </tr>
        <tr ng-repeat="row in $data">
            <td ng-repeat="column in columns"  ng-show="column.visible" sortable="column.field" ng-click="save(row)">
                {{row[column.field][column.subfield] || row[column.field]}}
                <span compile="column.getValue()" ></span>
            </td>
        </tr>
    </table>

and after one day effort I understand that the problem is using css class "ng-table" . I mentioned this to save your time so other than adding

params.total(data.length)

you should check your css too and the working code is :

    <table ng-table="tableParams" class="table   table-striped"  show-filter="{{::showFilter}}">
        <tr ng-show="showHeaders">
            <th class="th-select" ng-repeat="column in columns">{{column.title}}</th>
        </tr>
        <tr ng-repeat="row in $data">
            <td ng-repeat="column in columns"  ng-show="column.visible" sortable="column.field" ng-click="save(row)">
                {{row[column.field][column.subfield] || row[column.field]}}
                <span compile="column.getValue()" ></span>
            </td>
        </tr>
    </table>

I had the same experience with loadData + asynchronous load. On my side the problem was that the data returned by the API was an array of 2 other arrays meanwhile I was using only 1 of the 2 for my table. See below:

*.js

return $http(options).then(function (resp) {
        params.total(resp.data.users.length)
        return resp.data
    }

*.html

 <tr ng-repeat="row in usrCtrl.servicesTable.data.users" ng-if="row.Services.hasOwnProperty(usrCtrl.selectedService)">

By returning "resp.data.users" on javascript side and correctly looping on "usrCtrl.servicesTable.data" on html side then the pager appeared!

Loïc

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top