- Nady Shalaby
- Ajax, HTTP/HTTPS, Javascript, Query String, Request, XMLHttpRequest
- 0 Comments
- 11819 Views
There’re many ways to convert a JS object to query string, But every method has its Pros & Cons.
In this article we will discuss each method and how you can use it so you have a full grasp of each method and when you need apply it.
Table of Contents
Using "URLSearchParams" Class
This method is used to transform a simple JS object that has a depth of 1 level of properties.
const simple = {
foo: "foo",
bar: "bar",
one: 1,
two: 2
};
const queryString = new URLSearchParams(simple);
console.log(queryString.toString()); // "foo=foo&bar=bar&one=1&two=2"
We can also use it to decode a query string to its original object.
const queryString = "foo=foo&bar=bar&one=1&two=2"
const simple = new URLSearchParams(queryString);
const obj = Object.fromEntries(simple.entries());
console.log(obj);
/* {
bar: "bar",
foo: "foo",
one: "1",
two: "2"
} */
Using Our Custom Script (Recommended)
This method is used to transform a complex JS object that has endless depth of levels of properties.
function encode(object) {
function reducer(obj, parentPrefix = null) {
return function (prev, key) {
const val = obj[key];
key = encodeURIComponent(key);
const prefix = parentPrefix ? `${parentPrefix}[${key}]` : key;
if (val == null || typeof val === 'function') {
prev.push(`${prefix}=`);
return prev;
}
if (typeof val === 'boolean') {
prev.push(`${prefix}=${val.toString().toUpperCase()}`);
return prev;
}
if (['number', 'string'].includes(typeof val)) {
prev.push(`${prefix}=${encodeURIComponent(val)}`);
return prev;
}
prev.push(
Object.keys(val).reduce(reducer(val, prefix), []).join('&')
);
return prev;
};
}
return Object.keys(object).reduce(reducer(object), []).join('&');
}
const complex = {
format: 'xlsx',
modelClass: 'App\\Models\\User',
columns: [
'id',
'name',
'mobile',
'email',
'region.name',
'hijri_created_at',
'gregorian_created_at',
],
with: [
'region',
],
filters: [{
column: 'type',
value: 'regionManager',
},]
};
const queryString = encode(complex);
console.log(queryString);
// Output:
/*
"format=xlsx&modelClass=App%5CModels%5CUser&columns[0]=id&columns[1]=name&columns[2]=mobile&columns[3]=email&columns[4]=region.name&columns[5]=hijri_created_at&columns[6]=gregorian_created_at&with[0]=region&filters[0][column]=type&filters[0][value]=regionManager"
*/
We can also use it to decode a query string to its original object.
function decode(querystring) {
function parseValue(value) {
if (value === "TRUE") return true;
if (value === "FALSE") return false;
return isNaN(Number(value)) ? value : Number(value);
}
function dec(list, isArray = false) {
let obj = isArray ? [] : {};
let recs = list.filter((item) => {
if (item.keys.length > 1) return true;
obj[item.keys[0]] = parseValue(item.value);
});
let attrs = {};
recs.map((item) => {
item.key = item.keys.shift();
attrs[item.key] = [];
return item;
}).forEach((item) => attrs[item.key].push(item));
Object.keys(attrs).forEach((attr) => {
let nextKey = attrs[attr][0].keys[0];
obj[attr] = dec(attrs[attr], typeof nextKey === "number");
});
return obj;
}
return dec(
querystring
.split("&")
.map((item) => item.split("=").map((x) => decodeURIComponent(x)))
.map((item) => {
return {
keys: item[0]
.split(/[\[\]]/g)
.filter((n) => n)
.map((key) => (isNaN(Number(key)) ? key : Number(key))),
value: item[1],
};
})
);
}
const querystring =
"format=xlsx&modelClass=App%5CModels%5CUser&columns[0]=id&columns[1]=name&columns[2]=mobile&columns[3]=email&columns[4]=region.name&columns[5]=hijri_created_at&columns[6]=gregorian_created_at&with[0]=region&filters[0][column]=type&filters[0][value]=regionManager";
console.log(decode(querystring));
// Output:
/*
{
format: 'xlsx',
modelClass: 'App\\Models\\User',
columns: [ 'id', 'name', 'mobile', 'email', 'region.name', 'hijri_created_at', 'gregorian_created_at' ],
with: [ 'region' ],
filters: [ { column: 'type', value: 'regionManager' } ]
}
*/
Credits: @christoph-jeanluc-schneider
Related
administrator
CEO of CoreCave, I have earned my stripes as a seasoned Senior Full-Stack Web Developer. I'm skilled in a wide range of front-end and back-end languages, responsive frameworks, and databases. My approach to coding is marked by a strict adherence to the best practices, grounding my work in functionality and efficiency. I strive to tackle real-world problems, improve systems, and make a tangible difference in our digital world.