-2

I want to convert deep JSON to URL params string. I have json:

{ filter: { dir: 184}, b:'a'}

and

{ filter: [1,2,3], b:'a'}

So I want the result string like this:

 filter[dir]=188&b=a
 filter[]=1&filter[]=2&filter[]=3&b=a

How to do this in JavaScript (not Jquery)?

cyberlobe
  • 1,783
  • 1
  • 18
  • 30
Alexander Zakusilo
  • 1,466
  • 3
  • 16
  • 34
  • 1
    Seems like pretty simple rules, should be fairly easy with a loop and some thinking, building the string as you loop. Give it a try, come back with some attempted code if you get stuck – musefan Sep 29 '16 at 10:02
  • I know it. But I asked and ready solution for quick anwer. Do you have it? – Alexander Zakusilo Sep 29 '16 at 10:18
  • 1
    Thank you everybody. I found a solution here http://stackoverflow.com/questions/1714786/querystring-encoding-of-a-javascript-object – Alexander Zakusilo Sep 29 '16 at 10:53

2 Answers2

2

You could use an iterative and recursive style for the values.

function getString(o) {

    function iter(o, path) {
        if (Array.isArray(o)) {
            o.forEach(function (a) {
                iter(a, path + '[]');
            });
            return;
        }
        if (o !== null && typeof o === 'object') {
            Object.keys(o).forEach(function (k) {
                iter(o[k], path + '[' + k + ']');
            });
            return;
        }
        data.push(path + '=' + o);
    }

    var data = [];
    Object.keys(o).forEach(function (k) {
        iter(o[k], k);
    });
    return data.join('&');
}

var data1 = { filter: { dir: 184 }, b: 'a' },
    data2 = { filter: [1, 2, 3], b: 'a' },
    data3 = { filter: [1, 2, 3], b: 'a', c: { d: { e: 42 } } };

console.log(getString(data1));
console.log(getString(data2));
console.log(getString(data3));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • 1
    Loving that console display hack ;) Also, as you have made it recursive I feel I should up vote yours over mine... sad times :( – musefan Sep 29 '16 at 10:28
  • Thank you. The best solution is here. http://stackoverflow.com/questions/1714786/querystring-encoding-of-a-javascript-object – Alexander Zakusilo Sep 29 '16 at 10:57
0

OK, so I was actually quite interested in this problem and wanted to try to solve it for myself. Which means I may as well just post the solution here if it can help people:

function build(input) {
  var output = "";

  // Loop each property in the base object.
  for (var p in input) {
    var item = input[p];

    // Need to handle differently for Array, Object, and OTHER.
    if (item instanceof Array) {
      // Loop each array value and append to output.
      for (var x in item) {
        output += "&" + p + "[]=" + item[x];
      }
    } else if (item instanceof Object) {
      // Loop each sub object property and append to output.
      // NOTE: We assume only a single level of object depth, this is NOT a recursive solution.
      for (var x in item) {
        output += "&" + p + "[" + x + "]=" + item[x];
      }
    } else {
      // Any other object type is just appended to output as is.
      output += "&" + p + "=" + item;
    }
  }

  // Finally, if we have any output, trim the first leading '&' character.
  if (output.length > 0)
    output = output.substring(1);

  return output;
}

console.log(build({ filter: { dir: 184}, b:'a'}));
console.log(build({ filter: [1,2,3], b:'a'}));
.as-console-wrapper { max-height: 100% !important; top: 0; }
musefan
  • 47,875
  • 21
  • 135
  • 185
  • Thank you. That's it! But I found the best solution is here: http://stackoverflow.com/questions/1714786/querystring-encoding-of-a-javascript-object . I hope it will be helpfull for you too. – Alexander Zakusilo Sep 29 '16 at 10:58