Serialize object to URL GET parameters

https://ru.stackoverflow.com/questions/941984

by Alexey Demin

HTML

<textarea id="output"></textarea>

CSS

body,
textarea {
  margin: 0;
}

textarea {
  width: 100vw;
  height: 100vh;
  resize: none;
}

JavaScript

var obj = {
    dirty: "&%[]?",
    nullable: null,
    undef: undefined,
    numberProp: 123,
    now: new Date(),
    regex: /^[a-z]+$/i,
    boolProp: true,
    obj: {
      objProp1: "objStr",
      objProp2: false,
      nullable: null,
      objInObj: {
        aa: "aa",
        bb: true
      }
    },
    arr: [{
        arrProp11: "str",
        arrProp12: 321,
        arrProp13: true,
        arrProp14: {
          a: "absdefg",
          b: true
        }
      },
      {
        arrProp21: "rts",
        arrProp22: 987,
        arrProp23: false
      },
      ["arrInArr1", "arrInArr2"],
      [{
        test: "str"
      }],
      null,
      new Date()
    ]
  },
  getTypeOf = function(obj) {
    if (typeof obj === 'undefined') {
      return 'undefined';
    }
    if (obj === null) {
      return 'null';
    }
    return Object.getPrototypeOf(obj).constructor.name;
  },
  getUrlPairs = function(obj) {

    const pairs = [],
      objType = getTypeOf(obj);

    const simple = (path, val) => path + '=' + val,
      simpleEnc = (path, val) => simple(path, encodeURIComponent(val)),
      typeFunc = {
        null: simple,
        undefined: (path, val) => simple(path, ''),
        Number: simple,
        Boolean: simple,
        String: simpleEnc,
        RegExp: simpleEnc,
        Date: (path, val) => simpleEnc(path, val.toJSON()),
        Object: (path, val, dot = '.') => iterate(val, path + dot, name => name),
        Array: (path, val) => iterate(val, path, name => '[' + name + ']')
      };

    function iterate(obj, prefix, wrap) {
      for (const [name, val] of Object.entries(obj)) {
        const call = typeFunc[getTypeOf(val)];
        const tmp = call && call(prefix + wrap(name), val);
        call && tmp && pairs.push(tmp);
      }
    }

    typeFunc[objType] && typeFunc[objType]('', obj, '');

    return pairs;
  };

var res = getUrlPairs(obj);
document.getElementById("output").innerHTML =
  res.join("\n") +
  "\n\n" +
  res.join("&");