Search code examples
javascripturl-parametersnested-objectember-query-params

Serialize complex object with nested array and objects to build query params


Example of complex object which i want to serialize, so I can use it in url as query param

 var query =  {
        "page": {
            "number": 1,
            "size": 50
        },
        "sort": "engagement_total",
        "sort_direction": "asc",
        "filters": {
            "engagement_total": {
                "type": "range",
                "value": [
                    21,
                    46
                ]
            }
        }
    }

JSON.stringify(query)

result with stringify

'{"page":{"number":1,"size":50},"sort":"engagement_total","sort_direction":"asc","filters":{"engagement_total":{"type":"range","value":[21,46]}}}'

Desired result

filters%5Bengagement_total%5D%5Btype%5D=range&filters%5Bengagement_total%5D%5Bvalue%5D%5B%5D=21&filters%5Bengagement_total%5D%5Bvalue%5D%5B%5D=46&page%5Bnumber%5D=1&page%5Bsize%5D=50&sort=engagement_total&sort_direction=asc

Solution

  • let obj = {
        "page": {
            "number": 1,
            "size": 50
        },
        "sort": "engagement_total",
        "sort_direction": "asc",
        "filters": {
            "engagement_total": {
                "type": "range",
                "value": [
                    21,
                    46
                ]
            }
        }
    }
    
    var flattenObj = function(data) {
        var result = {};
        function recurse(cur, prop) {
            if (Object(cur) !== cur) {
                result[prop] = cur;
            } else if (Array.isArray(cur)) {
                for (var i = 0, l = cur.length; i < l; i++)
                    recurse(cur[i], prop + "[" + i + "]");
                if (l == 0)
                    result[prop] = [];
            } else {
                var isEmpty = true;
                for (var p in cur) {
                    isEmpty = false;
                    recurse(cur[p], prop ? prop + "[" + p + "]" : p);
                }
                if (isEmpty && prop)
                    result[prop] = {};
            }
        }
        recurse(data, "");
        return result;
    };
    let output = flattenObj(obj);
    let url = Object.entries(output).map(elem => (elem[0].replace(/\[[0-9]+\]/, '[]') + "=" + elem[1])).join("&")
    console.log("url:", url)
    console.log("encodeURI:", encodeURI(url))