1

Ember doesn't show the query params in the url if the query params value is the default value. But I'd like to show it. Is there an option to change this behavior to show rather than hide?

App.IndexController = Ember.ArrayController.extend({
  queryParams: ['type'],
  type: "horror"  // the default value, won't appear in URL or params
})
ahnbizcad
  • 10,491
  • 9
  • 59
  • 85

2 Answers2

5

Default values and serialization is explained in this guide section. Unfortunately, it doesn't give a way to include the default value, and I'm not sure if there is a way out of the box.

However, there is a little trick. Instead of putting your default value in the controller, use null and set the default value in your route when the query parameters are set up. This tricks Ember into thinking it's not the default value, when from your perspective it is.

App.IndexRoute = Ember.Route.extend({
    resetController: function(controller) {
        controller.set('type', 'horror');
        return this._super.apply(this, arguments);
    }
});

App.IndexController = Ember.ArrayController.extend({
    queryParams: ['type'],
    type: null
});
GJK
  • 37,023
  • 8
  • 55
  • 74
  • I use a query parameter application-wide for all routes. Does this mean I have to supply the default query param on every route? – ahnbizcad Apr 02 '15 at 17:30
  • No, just the controller where the query parameters are defined. (In your case, just for the application route.) – GJK Apr 02 '15 at 18:37
  • in your code, you use `arguments`. Is this meant to literally be `arguments`, or the arguments I would pass in, in this case, `type`?, – ahnbizcad Apr 06 '15 at 22:26
  • 1
    It's supposed to be `arguments`, as in the [arguments object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments). – GJK Apr 06 '15 at 22:53
  • I think this is cleaner than setting query params in the router. – ahnbizcad Apr 06 '15 at 23:19
  • Hm. When I us this solution, any calls of `this.get('propertyName')` results in a browser console error saying it was null, rather than the value defined in the route. – ahnbizcad Apr 06 '15 at 23:43
  • resetController seems to fire only when you leave the route, so it doesn't fire when you first go into the route, which is what is needed to display default query params – ahnbizcad Apr 15 '15 at 07:12
  • 1
    You can use `setupController` for when you first enter the route and `resetController` for subsequent leaving/re-entering. – GJK Apr 15 '15 at 14:11
  • the trouble with setupController for this case is that it doesn't have access to params or query params. – ahnbizcad Apr 15 '15 at 19:02
1

I tried setting the initial value to null, but it didn't always work: sometimes my query parameter would appear in the URL, and sometimes it wouldn't. I solved this by manipulating browser history via window.history.replaceState(), if the query parameter wasn't in the URL. I put the code in my setter in Ember.run.schedule('afterRender', this, function() {...}) so that my logic runs after Ember is done rendering.

export default Ember.Controller.extend({
    setMyParam: function(newValue) {
        if (newValue !== null && typeof(newValue) !== 'undefined') {
            Ember.set(this, 'myParam', newValue);
            Ember.run.schedule('afterRender', this, function() {
                window.location.toString().match(/^(.+?)(\?.+)$/); // $1 = base URL, $2 = query params
                var queryParams = RegExp.$2;
                if (queryParams) {
                    if (queryParams.indexOf('myParam') === -1) {
                        console.log('No myParam in query parameters. Setting myParam=' + newValue);
                        window.history.replaceState({}, document.title, window.location.toString() + '&myParam=' + newValue);
                    }
                } else {
                    // No query parameters, so add it as the first query parameter
                    console.log('No query parameters, so adding myParam=' + newValue + ' as the first query parameter.');
                    window.history.replaceState({}, document.title, window.location.toString() + '?myParam=' + newValue);
                }
            });
         } else {
             console.log('setMyParam: newValue=' + newValue + ' is null or undefined. Not setting it!');
         }
    }
});