1

Background: The user can filter a list based on tags, every tag is an Ember Data model. The selected filtering tags should be stored in the URL via query parameters. I also want to display the selected tags in the interface.

What's the best way to go about this?

I'm pretty sure I only want to store the IDs, but if I do this I have to maintain a separate variable / computed property where I store the actual record of the ID which comes from the query parameters. This kind of duplication seems wrong to me.

Apart from this issue I don't know if I should use an array query parameter or build an comma separated string of the IDs. If I do the former I end up with ugly URLs like ?tags=%5B"3"%5D. But doing the later means doing even more work.

So what's your approach to this kind of problem? I hope I'm missing something obvious that doesn't have so many downsides :)

stravid
  • 1,009
  • 7
  • 14

1 Answers1

1

Easy!

  1. Find out which non-alphanumeric characters are not getting encoded in URLs. Using this tool, I found these characters: ~!*()_-.
  2. Pick one character that is not used in your tag names. Let's say it's *. Use it as a delimiter.
  3. Use tag names for tag ids. Or at least enforce unique tag names.

Then you've got a nice readable query:

?tags=foo*bar*baz&search=quux

To implement custom query param serialization/deserialization, do this:

Ember.Route.reopen({
  serializeQueryParam: function(value, urlKey, defaultValueType) {
    if (defaultValueType === 'array') {
      return `${value.join('*')}`;
    }
    return this._super(...arguments);
  },

  deserializeQueryParam: function(value, urlKey, defaultValueType) {
    if (defaultValueType === 'array') {
      return value.split('*');
    }
    return this._super(...arguments);
  }
});

Demo: app, code.

If you must use numeric tag ids in query params (for example, your tag names aren't unique), then you need some more customization: app, code.

Andrey Mikhaylov - lolmaus
  • 23,107
  • 6
  • 84
  • 133
  • Thanks for your great answer Andrey! You really understood what I was after :) I'm using your approach in my application now, thanks again. Heads up: Your examples seem to be broken in Chrome on my computer? Something with ES6 syntax I assume, maybe you have some addon installed on your computer? Just wanted to point that out for the future. – stravid Mar 11 '16 at 08:56
  • You mean an example app is broken? Both of them? I can run them fine in Chrome, JSBin should take care of transpiling. – Andrey Mikhaylov - lolmaus Mar 11 '16 at 10:50