简体   繁体   中英

Convert a nested object/ associative array into a query string using JavaScript

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?

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.

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

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...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM