1

I have the following query string:

student.name.firstname=Foo&student.name.lastname=Bar&student.address=My%20Street

How to convert to nested object like this:

{
  student:{
    name:{
      firstname: "Foo",
      lastname: "Bar"
    },
    address: "My Street"
  }
}

I have tried the following code but something is wrong:

function convertQueryToMap(query) {
    var params = {};
    var vars = query.split('&');
    for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split('=');
        var subpairs;
        if (pair[0].includes('.')) {
            subpairs = pair[0].split('.');
            var object = {};
            subpairs.reduce(function(o, s, i) {
                if (i === subpairs.length-1) {
                    return o[s] = decodeURIComponent(pair[1]);
                } else {
                    return o[s] = {};
                }
            }, object);
        }
    }
    return params;
}

Do you know a solution?

4
  • I presume the address should not be part of the name object? Commented Oct 12, 2019 at 15:51
  • You'll want to reduce onto the params, not onto that object which you create again for each key-value pair. And then only create a new sub-object o[s] = {} when it does not already exist. Commented Oct 12, 2019 at 15:53
  • Also drop the if (pair[0].includes('.')). You'll want to create values for non-nested keys as well? Commented Oct 12, 2019 at 15:55
  • @Bergi: it was a typo, I edited my question. Thank you. Commented Oct 12, 2019 at 16:06

2 Answers 2

4

You can use reduce method to create nested structure and split method to split the query first on parts based on & and also to get key and value from each part.

const query = 'student.name.firstname=Foo&student.name.lastname=Bar&student.address=My%20Street'

const toObject = string => {
  return string.split('&').reduce((r, s) => {
    const [key, val] = s.split('=');

    key.split('.').reduce((a, e, i, ar) => {
      return a[e] || (a[e] = (ar[i + 1] ? {} : val.replace(/%20/g, ' ')))
    }, r);

    return r;
  }, {})
}

const result = toObject(query);
console.log(result)

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

1 Comment

How to handle empty query string?
1

You could decode the string, split for parts, then for keys and value and assign the value to the nested object.

function setValue(object, keys, value) {
    var last = keys.pop();
        
    keys.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value;
}

var string = 'student.name.firstname=Foo&student.name.lastname=Bar&user.address=My%20Street',
    result = {};
    
decodeURI(string).split('&').forEach(s => {
    var [key, value] = s.split('=');
    setValue(result, key.split('.'), value);
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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.