<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 "> Bitovi Blog - UX and UI design, JavaScript and Front-end development

Bitovi |

Can’d Goodies: JavaScript Query String Encoding and Decoding

Learn how to serialize JavaScript objects and arrays to URL query strings with can-param, and how to deserialize a query string into an object or array!

Chasen Le Hara

Chasen Le Hara

Twitter Reddit

CanJS has everything you need to build a web app’s front-end: components, templating, models, and more. We also publish all of the modules that provide the infrastructure for the higher-level APIs, including a utility library called can-util.

This week Justin hosted a training on the different DOM and JS utilities that are included in can-util:

CanJS’s mission is to balance stability and innovation, which is one reason why we prefer to publish all of the useful bits of CanJS as independent packages. In the spirit of making all of our code more modular, we’ve started the process of extracting can-util’s useful modules into their own packages.

Today I’d like to highlight two new modules we split this week: can-param and can-deparam, both of which make it easier to deal with the query string of a URL (the part after the ?).

Have you ever needed to parse what’s in a query string, or take an object and put it in the query string? Then these packages are for you!

Serializing JavaScript arrays and objects into query strings

can-param takes an array or object and can serialize it into a query string. Let’s look at an example:

var param = require("can-param");
param({foo: "bar"})          //-> "foo=bar"

In this example, we’re providing can-param an object and it returns the string foo=bar.

Hot tip: query strings support arrays and nested values! Check out these examples, where an array is being turned into a query string and a nested object gets serialized correctly:

param({foo: ["bar", "baz"]}) //-> "foo[]=bar&foo[]=baz"
param({foo: {bar: "baz"}})    //-> "foo[bar]=baz"

Last cool thing: can-param uses encodeURIComponent to encode special characters, so in the example below, & gets converted into %26:

param({foo: "bar & baz"}) //-> "foo=bar+%26+baz"

In the Weather Report Guide, we make a request to Yahoo’s Weather API with the location the user types in. To encode the location correctly (which could have spaces or special characters), we use can-param before making the fetch request. The fetch API is great, although it doesn’t provide any serialization for your parameters, making can-param a perfect fit for the problem.

Parsing query strings into JavaScript arrays or objects

can-deparam is the opposite of can-param: it can take a query string and turn it into an array or object.

Let’s say we’re writing some routing code that needs to run when the URL changes:

window.onhashChange = function() {
    // Need to change the route based on window.location.hash

In this example, we’re providing can-deparam the string and its returning an object.

If we go to #foo=bar&number=1234, we want an object with foo and number properties that have the values we need.

can-deparam is a perfect solution!

var deparam = require("can-deparam");
window.onhashChange = function() {
	var params = deparam(window.location.hash.substr(1));
	params// -> '{"foo" : "bar", "number": 1234}'

Here are some examples of decoding a query string that represents an array and nested object:

deparam("foo[]=bar&foo[]=baz"); // -> '{"foo" : ["bar", "baz"]}'
deparam("foo[bar]=baz"); // -> '{"foo" : {"bar": "baz"}}'

Last but not least, can-deparam used decodeURIComponent to decode special characters, so in the example below, %20 gets converted into a space and %26 gets converted into &:

deparam("foo=bar%20%26%20baz"); // -> '{"foo" : "bar & baz"}'

More goodies to come!

Both of these modules are useful on their own, which is why we’ve split them from can-util. The next version of can-util (3.4) will use them instead of its own implementation, and the next version of can (3.6) will do the same.

We’re going to continue extracting the useful modules from can-util and making small modules that are generally useful. If you have any questions or comments, please join us on our forums or Gitter chat!