745

Is there a fast and simple way to encode a JavaScript object into a string that I can pass via a GET request?

No jQuery, no other frameworks—just plain JavaScript :)

8
  • 1
    Why can't JQuery be a solution if there is an appropriate one for your solution? Commented Mar 30, 2017 at 22:38
  • 5
    @eaglei22 because at the time I was working on a project for an IPTV set top box device and no external libraries were allowed. ;-) Commented Mar 31, 2017 at 8:22
  • 1
    Thanks for the response. I see this specification from time to time and always wondered a scenario why. Well, now I got one, thanks! :) Commented Mar 31, 2017 at 13:48
  • 27
    @eaglei22 Because sometimes you don't want to load a large library to get one element by id. Commented Jun 26, 2017 at 20:46
  • most browsers support URLSearchParams now... Commented Mar 12, 2018 at 17:11

47 Answers 47

1
2
1

TypeScript version for PHP notation (no URL escaped version)

/**
 * Converts an object into a Cookie-like string.
 * @param toSerialize object or array to be serialized
 * @param prefix used in deep objects to describe the final query parameter
 * @returns ampersand separated key=value pairs
 *
 * Example:
 * ```js
 * serialize({hello:[{world: "nice"}]}); // outputs  "hello[0][world]=nice"
 * ```
 * ---
 * Adapted to TS from a StackOverflow answer https://stackoverflow.com/a/1714899/4537906
 */
const serialize = (toSerialize: unknown = {}, prefix?: string) => {
  const keyValuePairs = [];

  Object.keys(toSerialize).forEach((attribute) => {
    if (Object.prototype.hasOwnProperty.call(toSerialize, attribute)) {
      const key = prefix ? `${prefix}[${attribute}]` : attribute;
      const value = toSerialize[attribute];
      const toBePushed =
        value !== null && typeof value === "object"
          ? serialize(value, key)
          : `${key}=${value}`;
      keyValuePairs.push(toBePushed);
    }
  });

  return keyValuePairs.join("&");
};
Sign up to request clarification or add additional context in comments.

Comments

1

Use:

const objectToQueryParams = (o = {}) =>
  Object.entries(o)
    .map((p) => `${encodeURIComponent(p[0])}=${encodeURIComponent(p[1])}`)
    .join("&");

Refer to the below gist for more: https://gist.github.com/bhaireshm

Comments

0

Just another way (no recursive object):

   getQueryString = function(obj)
   {
      result = "";

      for(param in obj)
         result += ( encodeURIComponent(param) + '=' + encodeURIComponent(obj[param]) + '&' );

      if(result) //it's not empty string when at least one key/value pair was added. In such case we need to remove the last '&' char
         result = result.substr(0, result.length - 1); //If length is zero or negative, substr returns an empty string [ref. http://msdn.microsoft.com/en-us/library/0esxc5wy(v=VS.85).aspx]

      return result;
   }

alert( getQueryString({foo: "hi there", bar: 123, quux: 2 }) );

Comments

0

If you want to pass an entire object as a single parameter, e.g, ?filter={param1: "val1", param2: "val2"}:

const serializeObject = (obj) => {
  let objStr = JSON.stringify(obj);

  objStr = objStr.replace(/\{/g, encodeURIComponent("{"));
  objStr = objStr.replace(/}/g, encodeURIComponent("}"));
  objStr = objStr.replace(/:/g, encodeURIComponent(":"));

  return objStr;
};

let res = serializeObject({param1: "val1", param2: "val2"});
console.log("serializeObject:", res); //%7B"param1"%3A"val1","param2"%3A"val2"%7D
console.log("serializeObject-decoded:", decodeURIComponent(res)); //{"param1":"val1","param2":"val2"}

1 Comment

how to use? no idea to use
0

My implementation of encoding an object as a query string, using reduce:

export const encodeAsQueryString = (params) => (
  Object.keys(params).reduce((acc, key)=>(
    params.hasOwnProperty(key) ? (
      [...acc, encodeURIComponent(key) + '=' + encodeURIComponent(params[key])]
    ) : acc
  ), []).join('&')
);

Comments

0

Here is a simple implementation that gets an object and converts it to a query parameters string:

export function objectToQueryParams(queryParams: object): string {
  return queryParams ?
    Object.entries(queryParams).reduce((acc, [key, val], index) => {
      const sign = index === 0 ? '?' : '&';
      acc += `${sign}${encodeURIComponent(key)}=${encodeURIComponent(val)}`;
      return acc;
    }, '')
    : '';
}

1 Comment

You need encodeURIComponent around key and val like every other response here
0

Referring to the answer user187291, add "isArray" as a parameter to make the JSON nested array be converted.

data : {
    staffId : "00000001",
    Detail : [ {
        "identityId" : "123456"
    }, {
        "identityId" : "654321"
    } ],

}

To make the result,

staffId=00000001&Detail[0].identityId=123456&Detail[1].identityId=654321

use:

serialize = function(obj, prefix, isArray) {
    var str = [], p = 0;
    for (p in obj) {
        if (obj.hasOwnProperty(p)) {
            var k, v;
            if (isArray)
                k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
            else
                k = prefix ? prefix + "." + p + "" : p, v = obj[p];

            if (v !== null && typeof v === "object") {
                if (Array.isArray(v)) {
                    serialize(v, k, true);
                } else {
                    serialize(v, k, false);
                }
            } else {
                var query = k + "=" + v;
                str.push(query);
            }
        }
    }
    return str.join("&");
};

serialize(data, "prefix", false);

Comments

-1

const buildSortedQuery = (args) => {
    return Object.keys(args)
        .sort()
        .map(key => {
            return window.encodeURIComponent(key)
                + '='
                + window.encodeURIComponent(args[key]);
        })
        .join('&');
};

console.log(buildSortedQuery({
  foo: "hi there",
  bar: "100%"
}));

//bar=100%25&foo=hi%20there

Comments

-1

Just use the following:

encodeURIComponent(JSON.stringify(obj))

// elastic search example
let story ={
  "query": {
    "bool": {
      "must": [
        {
          "term": { 
            "revision.published": 0, 
          }
        },
        {
          "term": { 
            "credits.properties.by.properties.name": "Michael Guild"
          }
        },
        {
          "nested": {
            "path": "taxonomy.sections",
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "taxonomy.sections._id": "/science"
                    }
                  },
                  {
                    "term": {
                      "taxonomy.sections._website": "staging"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}


const whateva = encodeURIComponent(JSON.stringify(story))
console.log(whateva)

Comments

-1
const querystring=  {};

querystring.stringify = function (obj, sep = '&', eq = '=') {
  const escape = encodeURIComponent;
  const qs = [];
  let key = null;

  for (key in obj) if (obj.hasOwnProperty(key)) {
    qs.push(escape(key) + eq + escape(String(obj[key])));
  }
  return qs.join(sep);
};

Example:

const a  = querystring.stringify({a: 'all of them', b: true});
console.log(a);  // Output: a=all%20of%20them&b=true

Comments

-1
 let data = {
    id:1,
    name:'Newuser'
    };
const getqueryParam = data => {
  let datasize = Object.keys(data).length;
  let initial = '?';

  Object.keys(data).map(function (key, index) {
    initial = initial.concat(`${key}=${data[key]}`);
    index != datasize - 1 && (initial = initial.concat('&'));
  });
  console.log(initial, 'MyqueryString');
  return initial;
};

console.log(getqueryParam(data))//You can get the query string here

If you have baseUrl means to get full query use 

baseUrl.concat(getqueryParam(data))

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
-1

You can pass an object to this function with undefined properties. If the property exist, it will be converted to a query string and the query string will be returned.

    function convertToQueryString(props) {
      const objQueryString = { ...props };

      for (const key in objQueryString) {
        if (!key) {
          delete objQueryString[key];
        }
      }

      const params = JSON.stringify(objQueryString);



      const qs = params
        .replace(/[/''""{}]/g, '')
        .replace(/[:]/g, '=')
        .replace(/[,]/g, '&');

      console.log(qs)

      return qs;
    }

    convertToQueryString({order: undefined, limit: 5, page: 1})

2 Comments

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
The output seems to be "limit=5&page=1". Is that correct?
-1

While there are limits to query-string lengths that should be considered (for sending JSON data in HTTP/s GET calls versus using POST)...

JSON.stringify(yourJSON) will create a String from your JSON object.

Then just hex-encode it (link below).

That will work always versus various possible problems with base64 type URL encoding, UTF-8 characters, nested JSON objects and such.

References

JSON.stringify()

Encode String to HEX

Comments

-1

For TS

const convertQueryToString = (data: { [x: string]: any }): string => {
  const serialize = (obj: { [x: string]: any }, prefix?: string): string => {
    const str = [];
    let p;

    for (p in obj) {
      if (obj.hasOwnProperty(p)) {
        const k = prefix ? `${prefix}[${p}]` : p;
        const v = obj[p];

        str.push(
          v !== null && typeof v === 'object' ? serialize(v, k) : `${encodeURIComponent(k)}=${encodeURIComponent(v)}`
        );
      }
    }

    return str.join('&');
  };

  return serialize(data);
};

1 Comment

Welcome to SO! Please don't post code-only answers but add a little textual explanation about how and why your approach works and what makes it different from the other answers given. You can find out more at our "How to write a good answer" page.
-2

You can also achieve this by using simple JavaScript.

const stringData = '?name=Nikhil&surname=Mahirrao&age=30';
    
const newData= {};
stringData.replace('?', '').split('&').map((value) => {
  const temp = value.split('=');
  newData[temp[0]] = temp[1];
});

console.log('stringData: '+stringData);
console.log('newData: ');
console.log(newData);

1 Comment

This is a nice exercise, but this is the other way around. Not an answer to the question.
-2
const serialize = obj => Object.keys(obj).reduce((a, b) =>
    a.push(encodeURIComponent(b) + "=" + encodeURIComponent(obj[b])) && a,
    []).join("&");

Call:

console.log(serialize({a:1,b:2}));
// output: 'a=1&b=2

'

1 Comment

From review queue: May I request you to please add some context around your source-code. Code-only answers are difficult to understand. It will help the asker and future readers both if you can add more information in your post.
-3

With Ramda:

    R.pipe(R.toPairs, R.map(R.join('=')), R.join('&'))({a: 'b', b: 'a'})

1 Comment

This answer is specific to a framework, despite the OP explicitly stating they were looking for a vanilla Javascript solution: “No jQuery, no other frameworks - just plain Javascript :)”
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.