Jacob van Lingen
Jacob van Lingen

Reputation: 9537

Url encoding for query params in Ember.js

I am using Ember.js, version 1.7.0-beta.1, in my latest project. I use the query params feature to make a list survive a hard refresh (e.g. after a reload, the selected items in the list are still selected).

I got a controller whom manages that:

export default Ember.ObjectController.extend({
    queryParams: [{selectedFiles: 'files'}],
    selectedFiles: Ember.A([]), //list of file ids

    ... //other props

    actions: {
    selectFile: function(file) {
        //set or remove the file id to the selectedFiles property
    }
});

It works awesome, but with one condition: the url is url-encoded:

Chrome & IE:

path/354?files=%5B"6513"%2C"6455"%2C"6509"%2C"6507"%2C"6505"%2C"6504"%2C"6511"%5D

FF (automaticly sets the brackets):

path/354?files="6513"%2C"6455"%2C"6509"%2C"6507"%2C"6505"%2C"6504"%2C"6511"]

Is there a way in Ember to decode the query-param-string to a more readible format? Maybe I could use the decodeURIComponent() function somewhere?

The desired output:

path/354?files=["6513","6455","6509","6507","6505","6504","6511"]

Upvotes: 7

Views: 5397

Answers (1)

user1816877
user1816877

Reputation:

I had a very similar problem, and made it work by overriding serializeQueryParam and deserializeQueryParam in the route.

In the controller you would have:

queryParams: ['files'],
files: []

And in the route:

  serializeQueryParam: function(value, urlKey, defaultValueType) {
    if (defaultValueType === 'array') {
      return value;

      // Original: return JSON.stringify(value);
    }
    return '' + value;
  }, 

and:

  deserializeQueryParam: function(value, urlKey, defaultValueType) {

    if (defaultValueType === 'array') {

      var arr = [];
      for (var i = 0; i < value.length; i++) {
        arr.push(parseInt(value[i], 10));
      }      

      return arr;

      // Original: return Ember.A(JSON.parse(value));
    }

    if (defaultValueType === 'boolean') {
      return (value === 'true') ? true : false;
    } else if (defaultValueType === 'number') {
      return (Number(value)).valueOf();
    }
    return value;
  }, 

The url will then become something like:

?files[]=1&files[]=2&files[]=3

Which will then be a real array on the server side.

Take a look at this working example on jsbin.com

Upvotes: 11

Related Questions