Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

on-select page invoked twice on totalitems change #1079

Closed
djkprojects opened this issue Sep 26, 2013 · 13 comments
Closed

on-select page invoked twice on totalitems change #1079

djkprojects opened this issue Sep 26, 2013 · 13 comments

Comments

@djkprojects
Copy link

HTML Code:

<pagination on-select-page="foo(page)" page="currentPage" total-items="total" ....></pagination>

Controller Code:

$scope.currentPage = 20;
$scope.total = 20;
 ...
$scope.foo = function(page) {
   ...
   $http({...})
        .success(function(data, status) {
             ...
             $scope.total = 10;
             ...
        })
   ...
}

This scenario causes foo() being called twice due to https://github.com/angular-ui/bootstrap/blob/master/src/pagination/pagination.js#L57 and then https://github.com/angular-ui/bootstrap/blob/master/src/pagination/pagination.js#L45

The change of totalItems shouldn't invoke on-select-page

@bekos
Copy link
Contributor

bekos commented Sep 27, 2013

@djkprojects I would prefer a plunker to see what you are talking about, but the change of total-items does not always execute the on-select-page.
The only case when the change of total-items invokes the on-select-page is when it's change, reduces the number of available pages and the last page is smaller than the current page, and this is by design.

I don't know if you talk about this design decision as bug or about another situation.

@djkprojects
Copy link
Author

that's exactly the scenario you've described i.e.

"The only case when the change of total-items invokes the on-select-page is when it's change, reduces the number of available pages and the last page is smaller than the current page, and this is by design."

and if that's the case then I think on-select-page shouldn't be invoked because logically speaking user hasn't selected any page and it's just the number of items that has changed.

on-select-page should only get triggered on user click as its name suggests.

Perhaps a new directive would be a good idea: on-total-change?

Thanks

@bekos
Copy link
Contributor

bekos commented Sep 27, 2013

on-select-page is maybe misleading, probably on-page-change is a better name :-)
So, strictly speaking, when page is corrected in case of "overflow", there is a page selection.

Can you tell us what you are trying to do when a page is changed from user and do not want to do when a page is fixed from the directive? As you may see, this design decision was made since the initial implementation of the directive, and no one has complained.

@djkprojects
Copy link
Author

yes "on-page-change" definitely makes more sense ;)

What I'm trying to do is:

  1. Every time user changes the page (by clicking a number) foo() function gets triggered to pull data via $http - just like a standard data pagination (please note that due to amount of items I cannot load all of them at once)
  2. Let's say user is currently on the last page 560;
  3. I have an extra search form which when submitted also calls foo() with extra filter data but in this case it also resets the currentPage to 1 to reset the paginator.
  4. User submits it.
  5. What happens is the currentPage is changed to 1 before the $http call and then after that total-items gets updated depending on the number of items returned by $http. By changing total-items the currentPage=1 setting somehow gets lost and the paginator reverts back to page 560 which I believe is caused by the extra "on-select-page" call

If I remove "on-select-page" from the it works alright but then I'm unable to paginate through the data when changing pages.

@djkprojects
Copy link
Author

$scope.currentPage = 20;
$scope.total = 20;
...
$scope.foo = function(page, resetPage) {

if (resetPage) $scope.currentPage = 1;

$http({...})
.success(function(data, status) {
...
$scope.total = 10;
...
})
...
}

so if resetPage is set to true after $scope.total = 10; call I'd expect the paginator to stay on page 1 but that's not the case.

@bekos
Copy link
Contributor

bekos commented Sep 27, 2013

This seems like a very common use case.
The problem from what I see from your description, is that you try to change the page inside the foo which is called when the page is changed. The reset of the page should be made on the submit of the search form, and let the foo just fetch the results.

I hope you understand what I am saying but I cannot do much if you don't provide a plunker.

@djkprojects
Copy link
Author

Yes, resetPage is true for form submit only:

<pagination on-select-page=foo(page)" total-items="total" page="currentPage">

<form data-ng-submit="foo(1, 1)">

I'll try setting up plunker and let you know. Thanks

@bekos
Copy link
Contributor

bekos commented Sep 27, 2013

What i said is something like this <form data-ng-submit="currentPage = 1">

@bekos
Copy link
Contributor

bekos commented Sep 27, 2013

...but something more complex (ie when currentpage is 1, just fetch results)

@djkprojects
Copy link
Author

Here is the plunker: http://plnkr.co/edit/VSVZcO?p=preview

Note that when you select any page other than 1 and then submit the form the paginator should reset to 1 but it does only when you press "Go" twice. I've added console.log() so you can see that the values are definitely being set properly.

Also, when you remove foo() from on-select-page all works fine.

@bekos
Copy link
Contributor

bekos commented Sep 28, 2013

I would wait for a better plunker but the code should look like this: http://plnkr.co/edit/4tAKJX?p=preview

@djkprojects
Copy link
Author

Not sure how this is different from the original version apart from creating a new submit() function as it's still not really working as expected i.e. if you add:

if (page == 1) {
$scope.total = 60;
}

to fetchData() just to simulate new number of results then select last page and submit the form it will reset to the first page but straight after that another call is made (as a result of new total) and the paginator jumps back to the last page

  1. select last page: fetch data for page: 5,
  2. submit the form: fetch data for page: 1, fetch data for page: 3,

@bekos
Copy link
Contributor

bekos commented Sep 28, 2013

OK. I see the bug, and what is causing it is the order of firing the $watchers. This can happen and in other cases, you just happened to notice it through the on-select-page.

I 'll try to fix soon, but as a workaround for your case, until the fix is on the master, you can wrap the $scope.total=... in a $timeout.

Thx for reporting, but if we had a plunker from the start we would not have lost a day for this :-)

bekos added a commit to bekos/bootstrap that referenced this issue Sep 28, 2013
@bekos bekos closed this as completed in 81164da Sep 29, 2013
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants