10

I need to convert following type dictionary:

{'key1': ['value1'], 'key2': ['value1', 'value2']}

to key1=value1&key2=....

i.e. post data form. I am doing this inside chrome extention, the above dictionary of formdata is returned by:

chrome.webRequest.onBeforeRequest.addListener(function(details) {
      if(details.method=="POST")         // ajax call
      {
        message.postdata = details.requestBody.formData;
      }
      return {requestHeaders: details.requestHeaders};
 }, {urls: ["<all_urls>"],types: ["main_frame", "sub_frame"]}, ["blocking", "requestBody"]);

I remeber achieving the same using JQuery $.params() function. How can the same be done in javascript.

5 Answers 5

12

This is a mini jquery param API [fiddle].

You can use it through jqMini.param(obj);

as shown in the fiddle above, it provides the same output with jquery's original $.param function.

Note: jqMini.param does not handle the traditional jquery objects as parameters.

(function(w) {
    var app = {},
        class2type = {},
        toString = class2type.toString,
        r20 = /%20/g,
        rbracket = /\[\]$/;
    
    w.jqMini = app;
    
    app.type = function(obj) {
        if ( obj == null ) {
            return obj + "";
        }
        // Support: Android < 4.0, iOS < 6 (functionish RegExp)
        return typeof obj === "object" || typeof obj === "function" ?
            class2type[ toString.call(obj) ] || "object" :
        typeof obj;
    };
    
    app.isFunction = function(obj) {
        return app.type(obj) === "function";
    };
    
    app.buildParams = function(prefix, obj, add) {
        var name, key, value;
        
        if(Array.isArray(obj)) {
            for(var key in obj) {
                value = obj[key]
                if(rbracket.test(prefix))
                    add(prefix, value);
                else
                    app.buildParams(prefix + "[" + (typeof value === "object"? key: "") + "]", value, add );
            }
        } else if(app.type(obj) === 'object') {
            for(name in obj)
                app.buildParams(prefix + "[" + name + "]", obj[name], add);
        } else
            add(prefix, obj);
    };
    
    app.param = function(obj) {
        var prefix, key, value
        serialized = [],
            add = function(key, value) {
                value = app.isFunction(value)? value() : (value == null ? "" : value );
                serialized[serialized.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
            };
        
        if(Array.isArray(obj)) {
            for(key in obj) {
                value = obj[key];
                add(key, value);
            }
        } else {
            for(prefix in obj)
                app.buildParams(prefix, obj[prefix], add);
        }
        
        return serialized.join('&').replace(r20, '+');
    };
    
})(window);

var obj = {'key1': ['value1'], 'key2': ['value1', 'value2']};
console.log(jqMini.param(obj));

Sign up to request clarification or add additional context in comments.

5 Comments

Dude you should create a Gist with this code. Honestly it's being quite unused in this answer. I needed an alternative to $.param() for data obtained from a form by Angular JS and using jquery just for that was killing me. Thanks a lot!! +1
i is undefined in app.buildParams(prefix + "[" + (typeof v === "object"? i: "") + "]", value, add );
Can anyone explain what v and i are in this line ` app.buildParams(prefix + "[" + (typeof v === "object"? i: "") + "]", value, add );`
I am really curious where did you get v and i here ` app.buildParams(prefix + "[" + (typeof v === "object"? i: "") + "]", value, add );`
The v and i are the value and key variables. I've created this fiddle 5 years ago, and I guess I messed up when I was testing it.
10
function queryParams(source) {
  var array = [];

  for(var key in source) {
     array.push(encodeURIComponent(key) + "=" + encodeURIComponent(source[key]));
  }

  return array.join("&");
}

1 Comment

This doesn't work for nested objects. The answer below by @ryeballar figured it out
2

For those of you using AngularJS, you might want to check out $httpParamSerializerJQLike

Comments

1

This is what I came up with - it has the same array handling as jQuery param.

var queryParam = function( ary ) {
    return Object.keys( ary ).map( function( key ) {
        if ( Array.isArray( ary[key] ) ) {
            var arrayParts = [];
            for ( var i = 0; i< ary[key].length; i++ ) {
                arrayParts.push( encodeURIComponent( key + '[]' ) + '=' + encodeURIComponent( ary[key][i] ) );
            }
            return arrayParts.join( '&' );
        }
        return encodeURIComponent( key ) + '=' + encodeURIComponent( ary[key] );
    }).join('&');
};

Comments

0

Try this:

const data = {'key1': ['value1'], 'key2': ['value1', 'value2']};

const p = new URLSearchParams();
Object.keys(data).map((k) => data[k].map((v) => p.append(k+"[]",v)));

console.log(p.toString());

Output: key1%5B%5D=value1&key2%5B%5D=value1&key2%5B%5D=value2

Comments

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.