Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tableParams.reload() does not reload filter data #186

Closed
ghost opened this issue Jan 27, 2014 · 30 comments
Closed

tableParams.reload() does not reload filter data #186

ghost opened this issue Jan 27, 2014 · 30 comments

Comments

@ghost
Copy link

ghost commented Jan 27, 2014

i'm using tableParams.reload() (and params.total(filteredData.length)) which reloads the table with the new external data, but the selections in "select" and "select-multiple" filters do not change. tableParams.reload() should call the "filter-data" functions again, no? is there another way to accomplish this?

@DmitryFischenko
Copy link

Hi there. First of all - thanks for the project.
I have the same problem. I need to update filters with data fetched from a server, but have no idea how to trigger filter-data func.

@basilcronus
Copy link

I found that if you declare your data right within the getData function it seems to update the table.
So..... getData: function($defer, params){
var data = $scope.yourdata;
var orderedData = ...............................
}

@developersatish
Copy link

My data is loaded successfully on DOM but when i fetch the data from server and want to refresh the ng-table by tableParams.reload() its not reflecting the result, but when i click on sorting or paging then its reflecting the result.
what issue can be this?

@qwwqwwq
Copy link

qwwqwwq commented May 12, 2014

I'd like to second what @basilcronus suggested, this also worked for me. Would love to know what the reason for this is.

@kunkun-tang
Copy link

Had the same issue with @developersatish.
Wait for a resolution to this problem.

@hwatersiv
Copy link

Hi everyone. I just recently started using ngTable. Im having a similar issue especially with nested ngTables and reloading data separate to the parent data. here is a quick idea:

parent controller:

var parentData = [...];

$scope.details = -1

$scope.showDetails = function (id) {
$scope.details = id;
};

// ngTable ////////
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
sorting: {
id: 'asc' // initial sorting
}
}, {
total: parentData.length, // length of data
getData: function($defer, params) {
// use build-in angular filter
var orderedData = params.sorting() ?
$filter('orderBy')(parentData, params.orderBy()) :
parentData;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});

on the html I have an ng-click to send the id to this and change the details scope.

Child controller (Secondary table that relates to the first controller):

var childData = [...];

$scope.$parent.$watch('details', function () {
console.log("you made it here");
$scope.tableParams2.reload();
});

// child ngTable ////////
$scope.tableParams2 = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
sorting: {
id: 'asc' // initial sorting
}
}, {
total: childData.length, // length of data
getData: function($defer, params) {
// use build-in angular filter
var orderedData = params.sorting() ?
$filter('orderBy')(childData, params.orderBy()) :
childData;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
},
$scope: { $data: {} }
});

I can see the change when i click but my child table isn't updating. Not sure if this helps, but i do think it is related.

@tillschweneker
Copy link

Hi,
I'm also having the same issues as @developersatish. The table data is only updated after I sort or filter the table. Is there any solution to this issue?

@maeishoj
Copy link

maeishoj commented Jan 6, 2015

I have a similar issue.

On a click event I start retrieving data from a server (multiple calls).
So I have a for loop and in there I have GET requests and I store the results that return into a scope variable that I wanna plot in a table async.

However on click I instantiate my table as so:

`$scope.tableParams = new ngTableParams({
        page: 1, // show first page
        count: 10, // count per page
        sorting: {
            Country: 'asc' // initial sorting
        }
    }, {
        total: $scope.continentTableData.length, // length of data
        getData: function($defer, params) {
            for (var i = 0; i < numberOfCountries; i++) {
                try {
                    var country = $("path[class*=" + $scope.currentContinentCountries[i].toUpperCase() + "]")[0].__data__.properties.name;
                    MapService.getInfographicsData(2013, country, function(infrographicsData) {
                        counter++;
                        // debugger;
                        var cpi = infrographicsData[0].data.CPI;
                        var trace = infrographicsData[1].data;
                        var countryName;

                        if (cpi == null) {
                            countryName = trace.Ref_Country;
                        } else {
                            countryName = cpi.Country;
                        }

                        var joinedData = {
                            Country: countryName,
                            Cpi: cpi,
                            Trace: trace
                        }
                        $scope.continentData.push(joinedData);

                        $scope.continentTableData = $scope.continentData;

                        // if (counter==numberOfCountries-1) {
                        //     console.log("tier");
                            $timeout(function() {
                            // update table params
                            params.total($scope.continentTableData.length);
                            // set new data
                            console.log("new data set");
                            $defer.resolve($scope.continentTableData);
                        }, 1500);
                        // };

                    });
                } catch (e) {
                    // console.log(e);
                    continue;
                }                    
            }

            // $scope.$apply();
        }
    });`

as in the ngTable example with ajax. However nothing is shown in the table (getData never gets called.)

If I click "refresh" tableParams, Then the table starts loading everything except that each item is duplicated.

Any idea?

@telwing
Copy link

telwing commented Mar 19, 2015

@developersatish I was able to reflect new data from the server by copying the functionality attached to the pagination buttons.

$scope.tableParams.count(1);

I placed this in the callback of my request.

myRequest().then(function(response) {
    $scope.data = response;
    $scope.tableParams.total($scope.data.length);
    $scope.tableParams.count(1);
});

Edit:

In my original post, the 1 in $scope.tableParams.count(1) should actually be replaced with a variable that contains the value set to count in ngTableParams.
See http://embed.plnkr.co/harWG3J6OlNHzbOu0e6S/preview for a working example.

@kyleboyle
Copy link

Since this is the top search result for this problem, I'll include what i did for my solution. I simply stored in my $scope the array of {id,title} objects that is used as the argument to the defer.resolve in the filter-data function. (it could be / is probably empty initially.) You can then update that array at any time and the changes will be reflected in the filter select. So i update it when my ajax call brings back the server response.

Also in my case the table data set expands (is augmented) as the user expands the search range. This requires that I also modify (apply a diff to) the select filters.

@dcarr178
Copy link

I tried that but it doesn't work. Can you paste your working example?

@avneeshroks
Copy link

Hey Guys,
I have the same issue as @almaplayera, i have a scenario something like

1. The filterdata used in dropdown is coming from service

2. And to update the same data i have a section from where user can add new entries/ update the existing.

3. After Adding/Updating the entries from add/edit section filterdata for dropdown that dropdown should be refreshed once the table is reloading.

I am doing this to get my company data to filter-data -

screen4ngtable

After that i called the getCompany Method in filter-data of my view -

screen5ngtable

Can anyone please suggest any solutions to get my filter-data updated with the recent data from service Or provide some examples for alike use case.

@esvit : i have tried to get my data at getData callback in ngTablePrams and binded it to $scope after that i tried passing the same variable to filter-data in view something like @israelidanny suggested in #342 but that also is not working for me. :(

P.S : i am doing tableParams.reload(); after adding & editing.

@kyleboyle
Copy link

I no longer have my code as I switched away from ng table before I committed anything. However, going from memory:

The filter functions (your getCompany function) are only invoked once on table init. So you have to apply changes to the resolved data array whenever there are record changes and angular will apply those changes to the dom.

$scope.company_filter = [];

$scope.getCompanyFilter = function(data) {
  var def = $q.defer();
  companyService.getAll().success(function(response) {
    $scope.updateCompanyFilter(response.data);
    def.resolve($scope.company_filter);
  });
  return def;
};

$scope.updateCompanyFilter = function(data) {
  $scope.company_filter.length = 0;
  for (i in data) {
    $scope.company_filter.push({
        'id': data[i].id,
        'title': data[i].name
    });
  }
};

// Then wherever you refresh your table data, just call updateCompanyFilter(data).
// Or you could micro manage the filter array when you do adds/deletes instead of reseeding it every time.

<td ... filter-data="getCompanyFilter($column)" >

Again, i could be wrong since it's been a few months.

@rachithaShetty
Copy link

Is this issue fixed in the latest version of ng-table?

Could somebody provide an example code

@christianacca
Copy link
Collaborator

I don't think it is.

Now, I don't think it would be too difficult to make the
controller.loadFilterData function available to be called from the
tablParams. You would then be able to call this when the lists change in
your application.

C

On Fri, Jun 19, 2015 at 6:59 AM, rachithaShetty notifications@github.com
wrote:

Is this issue fixed in the latest version of ng-table?


Reply to this email directly or view it on GitHub
#186 (comment).

@avneeshroks
Copy link

👍 @kyleboyle : your solution rocks buddy, it worked for me..! Awesomeness...! Thanks a lot.

@vighneshiyer
Copy link

It appears that the resolution to this issue (Pull request 403: #403) was merged in v0.4.2, but the change that it made has since been reverted.

On line 549 of ng-table.js change

$scope.$watch('params.$params', function(newParams, oldParams) {
to
$scope.$watch('[params.$params, params.data]', function(newParams, oldParams) {

This resolved the issue with data being updated, but the table not refreshing to render the changes.
It appears that this bug was reintroduced in this commit: 9189e98#diff-6aca4bc06732c0635eb9860dc6cd040fL490

@christianacca
Copy link
Collaborator

Unfortunately $watch'ing params.data causes issues in certain circumstances:

when the elements within params.data are complex involving circular references, $watch'ing by value causes a stack overflow exception when angular.copy creates a deep clone.

I believe a newer version of angular.copy fixes this particular issue, however its still a bad idea to watch params.data by value for performance reasons.

@xuejingdong
Copy link

@kyleboyle This code works perfectly! Thanks! And adding the inArray function can filter out the duplicates.

    $scope.manufacturer_filter = [];
    $scope.getManufactFilter = function(column){
        var def = $q.defer();
        ResourseAPI.query(function(data){
            $scope.updateManufactFilter(data.devices);
            def.resolve($scope.manufacturer_filter);
        });
        return def;
    };
    $scope.updateManufactFilter= function(data) {
        var arr = [];

        angular.forEach(data, function (item) {
            if (inArray(item.manufacturer, arr) === -1) {
                arr.push(item.manufacturer);
                $scope.manufacturer_filter.push({
                    'id': item.manufacturer,
                    'title': item.manufacturer
                });
            }
        });
    };

    var inArray = Array.prototype.indexOf ?
    function (val, arr) {
        return arr.indexOf(val);
    } :
    function (val, arr) {
        var i = arr.length;
        while (i--) {
            if (arr[i] === val) return i;
        }
        return -1;
    };

@BartoGabriel
Copy link
Contributor

@kyleboyle Your solution is great.
Does anyone know if they could implement something similar but using ng-table-dynamic?
I load columns dynamically by javascript.

Example:

var column = {
    title: 'Example',
    sortable: 'example',
    filter: 'example',
        filterData: .....,
    show: true,
    field: 'example'
};

What should set property filterData? Or is there another way to reload data filters?

@christianacca
Copy link
Collaborator

There are lots of different ways to specify the array that the select filter will use as a datasource. Each of these methods apply to both ng-table and ng-table-dynamic.

Maybe the following code sample can help you figure something out?

http://codepen.io/christianacca/pen/JdqjxB?editors=101

@BartoGabriel
Copy link
Contributor

Good sample, but I can not find the solution to my problem. In all examples the data are loaded only once (sync or async) but they are not reloaded.

An example of what I get is:
I have two columns: Countries and cities, each one with a filter.
So:

  • When the country filter is null, prompted the server all cities.
  • When the country filter is selected, asking the server the only city that country applies and update the filterData of cities column.

It is understood? Sorry for my English.

Thanks for the reply.

@yaronguez
Copy link

@kyleboyle none of these solutions work for me (I'm not even doing any filtering) and I'm taking it as a sign of poor code quality that the table doesn't update when the underlying data does. What Angular table solution did you switch to?

@christianacca
Copy link
Collaborator

@BartoGabriel I think what you're trying to do is possible. A guy I worked with solved the problem by creating his own filter template that did exactly what you said. He overrode the select.html template in a similar fashion to the following example: http://codepen.io/christianacca/pen/xGeWGX?editors=101

Sorry I can't be more helpful, just pushed for time!

@christianacca
Copy link
Collaborator

Oh BTW, the guy I mentioned, he used the ui-select2

@BartoGabriel
Copy link
Contributor

@christianacca thanks for your help. It was very useful.
When I have the solution I will share.

@christianacca
Copy link
Collaborator

Cool :-)

@telwing
Copy link

telwing commented Sep 1, 2015

Hi guys, is my solution totally wrong or is @kyleboyle's just a better alternative?

@yaronguez
Copy link

@telwing your solution didn't work for me, but then again, neither did @kyleboyle 's . I'm not actually doing any filtering, though. I'm just sorting data from an array, $scope.users. When I remove an element from that array and call reload() on the table parameters, nothing happens. It's really surprising that something like this is so complicated unless I'm missing something basic.

@anujam523
Copy link

I'm also having the same issues as @developersatish.i also tried setting tableParams count but my getdata function call only at page load while filtering data by drop down list it is not able to call this function

$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 8, // count per page
sorting: {
LastSeen: 'desc' // initial sorting
},
filter: {
PatientName: '', // initial filter
},
}, {
filterSwitch: true,
getData: function ($defer, params) {
// use build-in angular filter
var filteredData = params.filter() ?
$filter('filter')($scope.items, params.filter()) :
$scope.items;

        var orderedData = params.sorting() ?
                            $filter('orderBy')(filteredData, params.orderBy()) : filteredData;
        params.total(orderedData.length); // set total for recalc pagination
        $scope.tableParams.count(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));

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



    }
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests