Resetting query params for link-to/transitionTo

I am trying to reset query parameters for a search page in my app, but navigation to the page is caching query params. I understand this is the default behavior, and it can be reset in various ways (this Github issue which poses a possible solution, as well as the guide page). However, the existing solutions I have found are leaving a lot to be desired.

My search page takes a large number of parameters (?address=xx&city=xx&state=xx…), therefore resetting the query params in every link-to is out of the question. I have global navigation links which shouldn’t use the cached query params. For example, clicking the “Search” link should give you a blank search page, which is pretty common functionality on the web.

I tried resetting each query param property in the resetController hook on the route, but I end up with a bunch of blank query params (?address=&city=&state=…) in my url, which works, but is ugly. Clearing the query params with a transitionTo results in the same long url with blank params.

Ideally, calling transitionTo({ queryParams: { address: 'foo' } }) should clear all other query params, and set only address, but it is instead just updating the address param, and leaving the rest as-is. Am I the only one who finds this very unintuitive and undesireable?

I don’t doubt that this behavior helps some scenarios. However, this is an area where Ember is making it difficult to do something that was once trivial, and seems to go against typical behavior of web applications.

Ideally, I’m looking for the following:

  1. An explanation of why this behavior (caching query params) was implemented as the default. A link to an existing discussion would be great.

  2. A solution that will give me clean URLs with only query params that are provided.

  3. A simple way to clear query params when clicking a link to the route I am currently on.

After some more work, I believe I may have solved my problem with the following:

1. Specify default query params in my controller.

queryParams: ['address', 'city', 'state'],
address: null,
city: null,
state: null

Not doing this prevents Ember from knowing how to properly clear the values, and remove them from future URLs. Leaving them undefined isn’t enough.

2. Don’t pass undefined query param values with transitionTo.

actions: {
  submitSearch: function () {
    var model = this.get('model').toJSON();
    
    // Create an object only with keys from model that have values (skip undefined values)
    var form = Object.keys(model).reduce(function (result, prop) {
      if (model[prop]) {
        result[prop] = model[prop];
      }
      return result;
    }, {});
    
    this.transitionToRoute('documents', { queryParams: form });
  }
}

Alternatively, if I set undefined values to null, I believe it would work similarly.

3. Use Route.resetController

resetController: function (controller) {
  var queryParams = controller.get('queryParams');
  queryParams.forEach(function (param) {
    controller.set(param, null);
  });
}

This clears the query params when you navigate away from the route, or the model changes. Essentially, it disables the query param caching.

4. Pass default query params in link-to.

{{#link-to "search" (query-params address='null' city='null' state='null')}}

Clicking a link to /search from another route doesn’t require this, but if you want to have /search links clear your query params while on the /search page, you need to provide default query param values. I have yet to find a better solution for this, since in my app, I have about 10 query parameters, and specifying all of them looks terrible.

I would be willing to contribute a change to the query-params helper if a better solution doesn’t exist, but someone has suggestions about how to do it.

7 Likes

Thanks, your solution does work as expected. But I’ve got another problem using query-params in link-to helper. If the queryParams are set to the default values, the activeClass on link-to won’t work when any of the queryParams is changed.

1 Like

This happens to me too , if there any solution , after a year? @ispiders

I use a mixin which seems to do the trick

export default Ember.Mixin.create({
  resetController: function (controller, isExiting) {
    if (isExiting) {
      var queryParams = controller.get('queryParams');

      // If query params were defined as hash params they come through in an Object
      if (queryParams.toString().slice(0,15) === "[object Object]") {
        queryParams = Object.keys(queryParams[0]);
      }

      // Set each param to null
      queryParams.forEach((param) => {
        controller.set(param, null);
      });
    }
  }
});
1 Like

going to try it , – that gonna be very useful.! Thanks.

@ismyrnow your resetController function is helpful to me. Thanks. I came across your post because as a newbie to ember I am struggling with the EXACT same issues. I’m trying to port an app from jquery and I’m having to roll my own “parameter manager” in ember exactly as I did with just jquery…which I think kind of defeats the purpose of even using ember.

Anyway, the specific problem I am having is that when certain actions are triggered, some params need to remain and some need to be reset. I wrote about it here: App design: managing complex state with sticky queryParams

Did you have a similar problem with your app, or did you just need a way to clear all params (i.e. override sticky-ness)? If you did have that problem, how did you deal with it? The code I am writing to manage parameter rules is ugly, ugly, ugly!