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 :)
/**
* 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("&");
};
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
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 }) );
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"}
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('&')
);
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;
}, '')
: '';
}
encodeURIComponent around key and val like every other response hereReferring 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);
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)
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
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))
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})
limit=5&page=1". Is that correct?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.
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);
};
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);
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
'
With Ramda:
R.pipe(R.toPairs, R.map(R.join('=')), R.join('&'))({a: 'b', b: 'a'})
URLSearchParamsnow...