ng-table not working for dynamic data
Asked Answered
P

6

4

I have created a table and I am using http to load the data in the tables. So, in every click, my table data is changing, but I don't see the updated data in the table. I had created a sample Plunker for the reference. In my project, WHen I click on Reload New Data, the data in table get's changed, but after 2-3 click it doesn't change. DId anyone know, how to fix it..

Pears answered 27/4, 2014 at 16:35 Comment(0)
C
4

It is a problem with the ngTable directive. It updates only when data.length changes. Take a look at this plunk. I set $scope['tableParams1'] to null and inside the $timeout I set the new data. This forces angularJs to do a new cycle. So in the first cycle the ngTable sees the data.length changed to 0 and in the new cycle the ngTable sees the data.length changed again. If you don't use the $timeout, the ngTable will see that the data.length remains the same as before and won't do nothing.

Chadbourne answered 27/4, 2014 at 17:22 Comment(4)
Thank you. It's working perfect, but the only problem I saw is: error in console Cannot read property 'settings' of null.. I had also earlier found this solution at Offical page of ng-table but thought may be there would be more alternative as it shows an error..Pears
@VishalKhode a very ugly hack to don't show any error in console: plnkr.co/edit/dtlKAHwy99jdnWVU0pc8?p=previewChadbourne
Even though that's ugly, but it's the most perfect solution i see now..Thanks a lot, marking this as an answer.. :)Pears
The plunk code does not seem to work anymore, I tried in multiple browser, getting some JS errors in the dev console.Cock
S
4

With some trial and error I found a seemingly better solution to the issue than indicated in the plunkrs. For clarity, I am using $resource in a service to fetch my data. When I add a record via a modal, at first it wouldn't upload the ng-table after closing the modal. I figured out a way that works for me:

// Get data from factory
var data = dataFactory.query();

//Use promise to load data to table, note the replacing of the second tableParams 
//object parameter with a function
data.$promise.then(function (data){
    $scope.tableParams = new ngTableParams({
        page: 1,            // show first page
        count: 10,
        sorting: {
            name: 'asc'
        },
        filter: {
            name: undefined             
        }
    }, resetTableParams()
    );
});

//The function that replaces the tableParams param
var resetTableParams = function(){
    return {
        total: data.length,
        getData: function($defer, params) {
            var filteredData = params.filter() ? $filter('filter')(data, params.filter()) : data;
            var orderedData = params.sorting() ? $filter('orderBy')(data, params.orderBy()) : filteredData; 

            params.total(orderedData.length);
            $defer.resolve($scope.data = orderedData.slice((params.page() -1) * params.count(), params.page() * params.count()));           
            }
    }
}

//A method to update the table that can be called when closing a modal
var updateTable = function(){
    data = dataFactory.query();
    data.$promise.then(function (data){
        $scope.tableParams.reload();
    });
}

// Add table row to table in modal and call updateTable() on closing modal
$scope.addRow = function(){
    var modalInstance = $modal.open({
        templateUrl: 'resources/partials/newrecord.html',
        controller: NewRecordModalCtrl
    })

    modalInstance.result.then(function(){
        updateTable();
    });
}

Unfortunately, I can't give a clear explanation as to why this works and other methods don't. For instance, if you would not use the resetTableparams() function but leave it hardcoded, the table does not update. Somehow, Angular's digest cycle likes this better :) If somebody has a good explanation, please share!

Spade answered 19/8, 2014 at 10:50 Comment(2)
It works awesome. But i dint get how it works. Can someone explain it pleaseRemaremain
The filtered data must be used also for the ordering, otherwise it is taking the unfiltered data if both filtering and ordering is applied: var filteredData = params.filter() ? $filter('filter')(data, params.filter()) : data; var orderedData = params.sorting() ? $filter('orderBy')(filteredData , params.orderBy()) : filteredData;Czechoslovak
S
3

You can directly use the provided method $scope.tableParams.reload();

Sum answered 1/6, 2015 at 10:23 Comment(0)
F
0

I'm not sure about the exact cause of the incorrect incrementing, but the problem here may be more due to the approach. You should attach the count to the scope via $scope.count, and then use the ng-click directive to increment it: <button type="button" ng-click="count++;".

It would also make it easier for you/others to read and debug if you externalized the $scope.tableParams and the data from $scope.table1 conditional thing:

$scope.count = 0;

var dataCollections = [
    [//.. first collection],
    [//.. second collection],
    [//.. third collection],
    [//.. fourth collection]
];

$scope.data = dataCollections[0];

$scope.$watch('count', function () {
    $scope.data = $scope.count < 4 ? dataCollections[$scope.count] : dataCollections[3];
});

I'm also not sure what you've got going on there with the $compile inside of the controller. It might make your task easier if you investigated some stuff about writing Angular controllers before delving into using a third-party module.

Functionalism answered 27/4, 2014 at 16:56 Comment(1)
Thanks for the reply. But actually I have created that plunker for an exmaple. In my case, I am using http service to get the data and I'm using that data in ng-table. If you want I can show you that code..Pears
O
0

I was working on ng-tables with dynamic data as well (adding/removing),
I was using an ajax call to make changes to the database, and the success: function() {} property make changes to the tableParams
but changes wouldn't show on the page unless i refreshed it, with a few console.log()'s, I found out that the success: function() {} actually never executes
but there's another function that always executes, complete: function() {} I know it's logically wrong to put the code that's supposed to work only after a successful call into complete: function() {} but if my success: function isn't working, this fix isn't that bad, especially knowing that the change is always successfully made to the database
it's strange because the success call works on other pages of the website, but it doesn't on some others. EDIT:
well, this fix still doesn't solve the problem when the length of the data doesn't change "editing the text in the data" as mentioned above,, frustrating...

$.ajax({
        type: "POST",
        url: /*some url*/,
        data: JSON.stringify({ /*some variable*/ }
        }),
        contentType: "application/json; charset=utf-8",
        dataType: "Json",
        success: function () {  // would never execute even if it's a successful call
            console.log("success"); 
        },
        error: function() {  // optional, personally didn't try it
            console.log("error"); 
        }
        complete: function () {  //always executes regardless of the result
            console.log("complete"); 
        }
    });
Overact answered 27/11, 2014 at 11:28 Comment(0)
C
0

To solve the issue, make sure you have set the ng-controller="yourController" only once in your page.

Code below will not update data:

<div ng-controller="yourController">
  <table ng-table = "tableParams" ng-controller = "yourController">
  </table>
</div>

Solve the issue by removing extra ng-controller in your html page:

<div ng-controller="yourController">
  <table ng-table = "tableParams">
  </table>
</div>
Chinese answered 6/4, 2016 at 5:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.