6

Is there a way to convert this object:

{
    lang: 'en-us',
    episode: 12
}

To a string with the following format?

"lang=en-us&episode=12"

Much like mapping an object to a query string, where each property is a query parameter.

I can do it like this:

var parameters = [];
for(var prop in obj)
   parameters.push(prop + '=' + obj[prop]);
return parameters.join('&');

But I was looking for a one-line solution. Is this possible?

PS: I cannot use jQuery and any of it utility functions. The solution must be in pure JavaScript.

Matias Cicero
  • 25,439
  • 13
  • 82
  • 154
  • 1
    ... Put it into a function? Unrelated, but if the values can be arbitrary, make sure you make them into URL-safe strings. – Dave Newton Sep 08 '15 at 18:40
  • 1
    A "one-line" requirement in JavaScript doesn't make much sense, as you can just put all the code in the same line. In what manner would the code be a one-line solution? – Guffa Sep 08 '15 at 18:40
  • 1
    duplicate: http://stackoverflow.com/questions/3308846/serialize-object-to-query-string-in-javascript-jquery – GPicazo Sep 08 '15 at 18:41

5 Answers5

17

You can use Array.prototype.map on the Object.keys array:

var data = {"lang": "en-us", "episode": 12};
var str = Object.keys(data).map(function (key) { 
  return "" + key + "=" + data[key]; // line break for wrapping only
}).join("&");
console.log(str);

With ES6, this becomes even more terse:

var data = {"lang": "en-us", "episode": 12};
var str = Object.keys(data).map(key => `${key}=${data[key]}`).join("&");
console.log(str);
ssube
  • 47,010
  • 7
  • 103
  • 140
4

You could use

var myObj ={"lang": "en-us", "episode": 12};
var str = Object.keys(myObj).map(key => key+"="+myObj[key]).join("&");

Whether or not this is any more readable is another question :)

Deftwun
  • 1,162
  • 12
  • 22
3
  • Object.entries (ES6)

    Object.entries returns [key, value] pairs, so we can destructure and map the pairs directly into ${key}=${value}:

    Object.entries(params).map(([key, value]) => `${key}=${value}`).join('&');
    // "lang=en-us&episode=12"
    

  • URLSearchParams

    For the specific use case of query strings, use URLSearchParams.toString:

    let searchParams = new URLSearchParams(params);
    
    searchParams.toString();
    // "lang=en-us&episode=12"
    

    URLSearchParams provides an interface with common utility methods, e.g.:

    searchParams.get('episode');
    // "12"
    
    searchParams.sort();
    // "episode=12&lang=en-us"
    
    searchParams.set('episode', 123456);
    // "episode=123456&lang=en-us"
    
tdy
  • 36,675
  • 19
  • 86
  • 83
2

All the other answers work perfectly,

However I've found that you can use URLSearchParams for the same thing...

var myObj = {keyOne: 'keyOneValue', keyTwo: 'keyTwoValue'};
var queryParams = new URLSearchParams(myObj).toString();
console.log(queryParams);
// keyOne=keyOneValue&keyTwo=keyTwoValue

see: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams

Craig Wayne
  • 4,499
  • 4
  • 35
  • 50
0

If the value contains equalTo (=) symbol, the accepted solution will not work.

Example

key1=a,key2=b,keyc=keyof=thec
accesskey=absdsfdfsa===

Solution:

Better to use Regex,

const a =
  'AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1';

  const output = {};

  a.split(';').forEach((v, i) => {
    const [key, value] = v.split(RegExp(/=(.*)/));
    output[key] = value;
  })

  console.log(output);

output Note: AccountKey contains == in value

{
  AccountName: 'devstoreaccount1',
  AccountKey: 'Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==',
  DefaultEndpointsProtocol: 'http',
  BlobEndpoint: 'http://127.0.0.1:10000/devstoreaccount1',
  QueueEndpoint: 'http://127.0.0.1:10001/devstoreaccount1',
  TableEndpoint: 'http://127.0.0.1:10002/devstoreaccount1'
}
Aravin
  • 6,605
  • 5
  • 42
  • 58