2

I want to use JavaScript to convert an object into a query string.

For example, I want to convert:

{
    a: 'hello',
    b: {
      b1: 'my',
      b2: 'friend',
      b3: {
          c: 90
      }
    }
}

to:

?a=hello&b%5Bb1%5D=my&b%5Bb2%5D=friend&b%5Bb3%5D%5Bc%5D=90

I have found quite a few answers to this here: Flatten a javascript object to pass as querystring , but they don't seem to deal with the issue of associative arrays (or objects within objects).

I found a good answer for JQuery which works fine by using jQuery.param, but i would like an answer using either native JS or Underscore.js.

How can I do this?

3 Answers 3

3

you can do this:

let obj = {
        a: 'hello',
        b: {
          b1: 'my',
          b2: 'friend',
          b3: {
              c: 90
          }
        }
    }

function getQueryString(obj, encode) {

      function getPathToObj(obj, path = []) {
        let result = [];

        for (let key in obj) {
          if (!obj.hasOwnProperty(key)) return;

          //deep copy
          let newPath = path.slice();
          newPath.push(key);

          let everyPath = [];
          if (typeof obj[key] === "object") {
            everyPath = getPathToObj(obj[key], newPath);
          } else {
            everyPath.push({
              path: newPath,
              val: obj[key]
            });
          }

          everyPath.map((item) => result.push(item))
        }

        return result;
      }

      function composeQueryString(paths) {
        let result = "";
        paths.map((item) => {
          let pathString = "";
          if (item.path.length > 1) {
            pathString = item.path.reduce((a, b, index) => {
              return a + '['+ b +']';
            })
          } else {
            pathString = item.path[0];
          }

          if (result) {
            pathString = "&" + pathString + '=' + item.val;
          } else {
            pathString = "?" + pathString + '=' + item.val;
          }

          result += pathString;
        });

        return result;
      }

      const str = composeQueryString(getPathToObj(obj));
      return encode === true ? encodeURI(str) : str;
    }
    console.log(getQueryString(obj, true));

get: ?a=hello&b%5Bb1%5D=my&b%5Bb2%5D=friend&b%5Bb3%5D%5Bc%5D=90

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

Comments

3

I highly recommend not trying to reinvent existing wheels. Your own implementation is probably going to be much less flexible and way more error-prone (have you thought about encoding the query string parameters correctly, for instance?) Instead, take a look at the query-string module.

7 Comments

What do you mean? I didn't add an implementation. I'm asking for an implementation. Also I believe that the URL I provided was encoded fine. Have a look at: freeformatter.com/url-parser-query-string-splitter.html and paste the URL and see for yourself.
All I'm saying is that the implementation you're GOING TO BE MAKING has a high probability of ending up much worse than already existing modules which pay attention to funky edge-cases and come with proper test suites.
Oh you mean just use a library
Exactly! :) query-string will solve your problem in no time. It comes from a well-known developer and if you take a look at the source you'll see it's not trivial to get these things right.
I have neither used Alloy nor Titanium, but if they really make it impossible/too hard to use third-party npm modules, I'd probably extract the relevant parts from the query-string module or just copy it altogether. It only has two dependencies: One brings the Object.assign method to Node-versions 4 and under (hoping you don't need this in Titanium/Alloy), and the other one (strict-uri-encode) is basically one line of code.
|
1

With Axios you can easily achieve this:

const instance = axios.create({
  url: '/user',
  baseUrl: 'https://my-api-server'
});
const config = {
  params: {
    a: 'hello',
    b: {
      b1: 'my',
      b2: 'friend',
      b3: {
        c: 90
      }
    }
  }
}
const uri = instance.getUri(config)
document.write(uri)
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

For more information you can visit this answer.

Good Luck...

1 Comment

Saved me a lot of time and even more lines of code..

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.