39

I realize that fundamentally I'm probably going about this the wrong way so I'm open to any pushes in the right direction.

I'm trying to use the HipChat API to send a notification to a room like so:

https://www.hipchat.com/docs/api/method/rooms/message

I'm trying to build the URL in the example with a js object's parameters, so basically I'm trying to convert this:

var hipChatSettings = {
            format:"json",
            auth_token:token,
            room_id: 1,
            from: "Notifications",
            message: "Message"
        }

To this:

https://api.hipchat.com/v1/rooms/message?format=json&auth_token=token&room_id=1&from=Notifications&message=Message

1

5 Answers 5

51

You should check this jQuery.param function.

var params = { width:1680, height:1050 };
var str = jQuery.param( params );
console.log(str);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

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

6 Comments

(I should have stated I was using jQuery but you oobviously read my mind) :)
He didn't read your mind. Just that on Stack Overflow when you ask something about JavaScript, you will get ninety jQuery answers, even if you explicitly say you don't want jQuery answers. Remember this in the future when you want a non-jQuery JavaScript answer. ;)
@L0j1k You are right, but jQuery answers can be useful for other people coming here from google even when they are useless for OP. So I think it is good fashion.
He didn't read your mind. He looked at your key words. So this escaped my usual downvote for such a practice.
@AdrianBartholomew I assume by "key words" you mean the tags, but the jQuery tag wasn't added until after this answer was posted
|
46
Object.keys(hipChatSettings).map(function(k) {
    return encodeURIComponent(k) + "=" + encodeURIComponent(hipChatSettings[k]);
}).join('&')
// => "format=json&auth_token=token&room_id=1&from=Notifications&message=Message"

Warning: newish JavaScript. If you want it to work on ancients, shim or rewrite into for.

Comments

13

Something like this could work for you

var str = "?" + Object.keys(hipChatSettings).map(function(prop) {
  return [prop, hipChatSettings[prop]].map(encodeURIComponent).join("=");
}).join("&");

// "?format=json&auth_token=token&room_id=1&from=Notifications&message=Message"

If you can't depend on ECMAScript 5, you can use a simple for loop

var pairs = [];

for (var prop in hipChatSettings) {
  if (hipChatSettings.hasOwnProperty(prop)) {
    var k = encodeURIComponent(prop),
        v = encodeURIComponent(hipChatSettings[prop]);
    pairs.push( k + "=" + v);
  }
}

var str = "?" + pairs.join("&");

1 Comment

I like this answer. For ES6 you can tweak a bit further to function makeParams(params) => { return params ? '?' + Object.keys(params).map((key) => ([key, params[key]].map(encodeURIComponent).join("="))).join("&") : '' } which you can just append onto your path, path + makeParams(params) and it handles undefined, null and {}
4

ES6 version, can do really nested objects with arrays

encodeURI(getUrlString({a: 1, b: [true, 12.3, "string"]}))

getUrlString (params, keys = [], isArray = false) {
  const p = Object.keys(params).map(key => {
    let val = params[key]

    if ("[object Object]" === Object.prototype.toString.call(val) || Array.isArray(val)) {
      if (Array.isArray(params)) {
        keys.push("")
      } else {
        keys.push(key)
      }
      return getUrlString(val, keys, Array.isArray(val))
    } else {
      let tKey = key

      if (keys.length > 0) {
        const tKeys = isArray ? keys : [...keys, key]
        tKey = tKeys.reduce((str, k) => { return "" === str ? k : `${str}[${k}]` }, "")
      }
      if (isArray) {
        return `${ tKey }[]=${ val }`
      } else {
        return `${ tKey }=${ val }`
      }

    }
  }).join('&')

  keys.pop()
  return p
}

2 Comments

actually only this answer works for multi level nested objects/arrays, except jQuery one, but jQuery lib is too big if used only for this single purpose
Works great with nested objects, this is the best I found, I only added encodeURIComponent(val).
4

Late to the dance but I quite enjoyed the brevity of this:

  Object.entries(hipChatSettings)
    .map(
      ([key, val]) => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`
    )
    .join("&");

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.