ui-router: Problem with reloadOnSearch: false - change in stateParams doesn't reload

Here is my issue:

I navigate through a list of links, that display different images depending on the date in the search parameters (?from&to).

Those search parameters should not trigger a state reload. Finally, here is my state declaration:

state('links/:linkId', {
  url: "/links/linkId?from&to",
  reloadOnSearch: false,
  templateUrl: ...
  Controller: ...
});

But then a huge problem shows up! When I try to navigate through my different links, reload doesn’t happen anymore, so that I cannot pass from one link to another.

After some digging in the code, I found out that when reloadOnSearch equals to false, triggers are always blocked because there’s absolutely no checking of whether the changing parameters are search parameters or path parameters.

So actually, reloadOnSearch doesn’t work as intended and should be renamed reloadOnStateParamsChange.

I fixed the issue by checking if the state parameters that changed are search parameters or not, which seems to work fine.

Please tell me if I’m mistaking somewhere or if it is relevant, and also if you would be interested in a pull request or a plunkr.

Thanks in advance!

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Comments: 35 (13 by maintainers)

Commits related to this issue

Most upvoted comments

My hilarious hack for this is as follows

//set the reloadOnSearch on state to false initially in some code block $state.current.reloadOnSearch = false;

// update query string here $location.search({“from”: 1, “to”: 2});

//revert reloadOnSearch on the state! $timeout(function () { $state.current.reloadOnSearch = undefined; });

@TEHEK A workaround is to make your state abstract and define reloadOnSearch true (which it is by default) and create a child state that only defines a url with the query string parameters you want to not cause a state reload.

E.g.:

.state('contacts', {
  url: '/contacts',
  abstract: true,
  template: '<h1>Contacts</h1>',
  controller: ['$scope', 
      function($scope) {
         //will not reload controller or view when contacts.content state changes
      }], 
   onEnter: function() {
      console.log("OnEnter: contacts");
  }
})
.state('contacts.content', {
  url: '?param1&param2&interestedDirectivesWillWatchMe',
  onEnter: function() {
      console.log("OnEnter: contacts.content");
  }
})