How to create query parameters in Javascript?
Asked Answered
T

18

220

Is there any way to create the query parameters for doing a GET request in JavaScript?

Just like in Python you have urllib.urlencode(), which takes in a dictionary (or list of two tuples) and creates a string like 'var1=value1&var2=value2'.

Timbering answered 21/9, 2008 at 17:46 Comment(1)
Reverse question: url - How can I get query string values in JavaScript? - Stack OverflowNicaea
M
232

Here you go:

function encodeQueryData(data) {
   const ret = [];
   for (let d in data)
     ret.push(encodeURIComponent(d) + '=' + encodeURIComponent(data[d]));
   return ret.join('&');
}

Usage:

const data = { 'first name': 'George', 'last name': 'Jetson', 'age': 110 };
const querystring = encodeQueryData(data);
Metalwork answered 21/9, 2008 at 17:53 Comment(7)
When iterating with for, use hasOwnProperty to ensure interoperability.Advertise
@troelskn, good point... although in this case, someone would have to be extending Object.prototype to break it, which is a pretty bad idea to start with.Metalwork
@Metalwork Why is it a bad ideia?Vendible
@Cesar, see: #3833117**Metalwork
Downvote because I have no idea whether this solution acts according to the specification and will always work. Prefer the standard URLSearchParams that is now available. OP please consider retreating this outdated answer.Vadose
this is insufficient. encodeQueryData({foo:{bar:123}}) returns foo=%5Bobject%20Object%5D , but the correct return value would be foo%5Bbar%5D=123Benn
This is the new correct way. function encodeQueryData(data) { return new URLSearchParams(data).toString(); }Marmara
A
263

URLSearchParams has increasing browser support.

const data = {
  var1: 'value1',
  var2: 'value2'
};

const searchParams = new URLSearchParams(data);

// searchParams.toString() === 'var1=value1&var2=value2'

Node.js offers the querystring module.

const querystring = require('querystring');

const data = {
  var1: 'value1',
  var2: 'value2'
};

const searchParams = querystring.stringify(data);

// searchParams === 'var1=value1&var2=value2'
Anadem answered 26/8, 2018 at 16:41 Comment(3)
Definitely the clean and modern approach. You can also later freely call searchParams.append(otherData)Manley
URLSearchParams will parse White space as '+' instead of '%20'. For example, new URLSearchParams({ abc: 'a b c' }).toString()result in 'abc=a+b+c'Fajardo
How is it that in 2021 there is not a more standardized way of achieving this? For example, what about adding ? only when searchParams are not blank.Egeria
M
232

Here you go:

function encodeQueryData(data) {
   const ret = [];
   for (let d in data)
     ret.push(encodeURIComponent(d) + '=' + encodeURIComponent(data[d]));
   return ret.join('&');
}

Usage:

const data = { 'first name': 'George', 'last name': 'Jetson', 'age': 110 };
const querystring = encodeQueryData(data);
Metalwork answered 21/9, 2008 at 17:53 Comment(7)
When iterating with for, use hasOwnProperty to ensure interoperability.Advertise
@troelskn, good point... although in this case, someone would have to be extending Object.prototype to break it, which is a pretty bad idea to start with.Metalwork
@Metalwork Why is it a bad ideia?Vendible
@Cesar, see: #3833117**Metalwork
Downvote because I have no idea whether this solution acts according to the specification and will always work. Prefer the standard URLSearchParams that is now available. OP please consider retreating this outdated answer.Vadose
this is insufficient. encodeQueryData({foo:{bar:123}}) returns foo=%5Bobject%20Object%5D , but the correct return value would be foo%5Bbar%5D=123Benn
This is the new correct way. function encodeQueryData(data) { return new URLSearchParams(data).toString(); }Marmara
E
83

functional

function encodeData(data) {
    return Object.keys(data).map(function(key) {
        return [key, data[key]].map(encodeURIComponent).join("=");
    }).join("&");
}   
Exscind answered 20/8, 2012 at 15:31 Comment(4)
Nice one! .map() has been implemented in JavaScript 1.6 so almost all browsers, even the granny ones support it. But as you can guess IE does not except IE 9+. But do not worry, there is a workaround. Source: developer.mozilla.org/en-US/docs/JavaScript/Reference/…Astrosphere
var data = { bloop1: true, bloop2: "something" }; var url = "https://something.com/?"; var params = encodeData(data); var finalUrl = url + params; // Is this the right use? Should produce https://www.something.com/?bloop1=true&bloop2=something ?Farreaching
@DylanHunt: Yup…Jasen
this is insufficient. encodeData({foo:{bar:123}}) returns foo=%5Bobject%20Object%5D , but the correct return value would be foo%5Bbar%5D=123Benn
D
42

Zabba has provided in a comment on the currently accepted answer a suggestion that to me is the best solution: use jQuery.param().

If I use jQuery.param() on the data in the original question, then the code is simply:

const params = jQuery.param({
    var1: 'value',
    var2: 'value'
});

The variable params will be

"var1=value&var2=value"

For more complicated examples, inputs and outputs, see the jQuery.param() documentation.

Delmadelmar answered 23/7, 2015 at 22:38 Comment(0)
U
29

The built-in URL class provides a convenient interface for creating and parsing URLs.

There are no networking methods that require exactly a URL object, strings are good enough. So technically we don’t have to use URL. But sometimes it can be really helpful.

👇 Example

let url = new URL("https://google.com/search");
url.searchParams.set('var1', "value1");
url.searchParams.set('var2', "value2");
url.searchParams.set('var3', "value3");
url.searchParams.set('var4', "value4 has spaces");

console.log(url)
Undistinguished answered 11/9, 2022 at 9:17 Comment(3)
I was scrolling searching for this one.Collings
Don't forget to convert url object to string with url.toString()Aboveground
const url = new URL("/some-route"); throws "'URL': Invalid URL" error.Indignant
J
15

ES2017 (ES8)

Making use of Object.entries(), which returns an array of object's [key, value] pairs. For example, for {a: 1, b: 2} it would return [['a', 1], ['b', 2]]. It is not supported (and won't be) only by IE.

Code:

const buildURLQuery = obj =>
      Object.entries(obj)
            .map(pair => pair.map(encodeURIComponent).join('='))
            .join('&');

Example:

buildURLQuery({name: 'John', gender: 'male'});

Result:

"name=John&gender=male"
Jasen answered 20/5, 2018 at 15:10 Comment(0)
K
10

We've just released arg.js, a project aimed at solving this problem once and for all. It's traditionally been so difficult but now you can do:

var querystring = Arg.url({name: "Mat", state: "CO"});

And reading works:

var name = Arg("name");

or getting the whole lot:

var params = Arg.all();

and if you care about the difference between ?query=true and #hash=true then you can use the Arg.query() and Arg.hash() methods.

Kakaaba answered 30/9, 2013 at 17:38 Comment(0)
A
9

This should do the job:

const createQueryParams = params => 
      Object.keys(params)
            .map(k => `${k}=${encodeURI(params[k])}`)
            .join('&');

Example:

const params = { name : 'John', postcode: 'W1 2DL'}
const queryParams = createQueryParams(params)

Result:

name=John&postcode=W1%202DL
Augite answered 16/3, 2018 at 17:18 Comment(2)
I've later realized that it's actually a slightly different version of @manav's response below. But anyway, it could still be preferable for ES6 syntax.Augite
First of all, you are not encoding the keys. Also, you should use encodeURIComponent() instead of encodeURI. Read about the difference.Jasen
N
8

If you are using Prototype there is Form.serialize

If you are using jQuery there is Ajax/serialize

I do not know of any independent functions to accomplish this, though, but a google search for it turned up some promising options if you aren't currently using a library. If you're not, though, you really should because they are heaven.

Nu answered 21/9, 2008 at 17:49 Comment(1)
jQuery.param() takes object and transform it to GET query string (this function better matches the question).Grumpy
P
3

A little modification to typescript:

  public encodeData(data: any): string {
    return Object.keys(data).map((key) => {
      return [key, data[key]].map(encodeURIComponent).join("=");
    }).join("&");
  }
Psychopathist answered 8/11, 2016 at 13:43 Comment(0)
L
3

Just like to revisit this almost 10 year old question. In this era of off-the-shelf programming, your best bet is to set your project up using a dependency manager (npm). There is an entire cottage industry of libraries out there that encode query strings and take care of all the edge cases. This is one of the more popular ones -

https://www.npmjs.com/package/query-string

Legion answered 30/5, 2017 at 23:59 Comment(1)
Very unspecific answer.Vadose
J
2
const base = "https://www.facebook.com"
const path = '/v15.0/dialog/oauth'
const params = new URLSearchParams({
    client_id: clientID,
    redirect_uri: redirectUri,
    state: randomState,
})
const url = new URL(`${path}?${params.toString()}`, base)

Here's an example to create query parameters and build URL from base using only JavaScript built-in constructor. This is part of Facebook Login implementation in manual approach.

According to URLSearchParams doc's example, there's a line

const new_url = new URL(`${url.origin}${url.pathname}?${new_params}`);

and I've followed that practice.

This is by far the most standardized way to build URL I believe.

I was a bit surprised that JavaScript doesn't supports query or fragment arguments in thier URL constructor still in 2023, despite It's definately worth having that.

Jodhpur answered 8/2, 2023 at 2:2 Comment(0)
E
2

Build URL with parameters in JavaScript

Construct URL without parameters

const apiEndPoint = new URL('https://geocode.maps.co/reverse');

Organise parameters in object form

const parameters = {
    lat: 52.508,
    lon: 13.381
}

Construct search parameters from object

const searchParams = new URLSearchParams(parameters)

Add search parameters to URL

apiEndPoint.search = searchParams

Final URL

const finalURL = apiEndPoint.toString()

Print completed URL on console

console.log(finalURL)

[Log] https://geocode.maps.co/reverse?lat=52.508&lon=13.381

Errhine answered 18/7, 2023 at 20:51 Comment(1)
How is this answer different from the most upvoted answer?Kristankriste
I
1

Here is an example:

let my_url = new URL("https://stackoverflow.com")
my_url.pathname = "/questions"

const parameters = {
    title: "just",
    body: 'test'
}

Object.entries(parameters).forEach(([name, value]) => my_url.searchParams.set(name, value))

console.log(my_url.href)

Ichthyosis answered 1/2, 2022 at 14:10 Comment(0)
H
0

I have improved the function of shog9`s to handle array values

function encodeQueryData(data) {
    const ret = [];
    for (let d in data) {
        if (typeof data[d] === 'object' || typeof data[d] === 'array') {
            for (let arrD in data[d]) {
                ret.push(`${encodeURIComponent(d)}[]=${encodeURIComponent(data[d][arrD])}`)
            }
        } else if (typeof data[d] === 'null' || typeof data[d] === 'undefined') {
            ret.push(encodeURIComponent(d))
        } else {
            ret.push(`${encodeURIComponent(d)}=${encodeURIComponent(data[d])}`)
        }

    }
    return ret.join('&');
}

Example

let data = {
  user: 'Mark'
  fruits: ['apple', 'banana']
}

encodeQueryData(data) // user=Mark&fruits[]=apple&fruits[]=banana
Hamite answered 8/10, 2020 at 9:58 Comment(1)
this is an improvement, yes, but it's still insufficient: encodeQueryData({foo:{bar:123}}) returns foo[]=123 , but the correct return value would be foo%5Bbar%5D=123Benn
L
0

By using queryencoder, you can have some nice-to-have options, such custom date formatters, nested objects and decide if a val: true will be just value or value=true.

const { encode } = require('queryencoder');

const object = {
    date: new Date('1999-04-23')
};

// The result is 'date=1999-04-23'
const queryUrl = encode(object, {
    dateParser: date => date.toISOString().slice(0, 10)
});
Levity answered 27/6, 2021 at 11:11 Comment(0)
B
0

A slightly improved version that removes empty values from the result:

function createQueryParams (params) {
  return Object.keys(params).filter(k => params[k])
    .map(k => `${k}=${encodeURIComponent(params[k])}`)
    .join('&');
}
Belong answered 29/5, 2023 at 15:34 Comment(0)
A
-13

This thread points to some code for escaping URLs in php. There's escape() and unescape() which will do most of the work, but the you need add a couple extra things.

function urlencode(str) {
str = escape(str);
str = str.replace('+', '%2B');
str = str.replace('%20', '+');
str = str.replace('*', '%2A');
str = str.replace('/', '%2F');
str = str.replace('@', '%40');
return str;
}

function urldecode(str) {
str = str.replace('+', ' ');
str = unescape(str);
return str;
}
Atalaya answered 21/9, 2008 at 17:50 Comment(1)
encodeURIComponent handles this and doesn't incorrectly use + for a space.Hydride

© 2022 - 2024 — McMap. All rights reserved.