3

How to append comma seperated values to url as search params using history.pushsate. with use of , RFC 3986, specifies that URI path components should not contain unencoded reserved characters and comma is one of those reserved characters. https://www.rfc-editor.org/rfc/rfc3986.

#code

window.history.pushState('new', 'inventory', '/new');

#Desired result

https://www.test.com/new?Year=2020,2019&Pricerange=10001-20000,20001-30000,30001-40000&Mileagerange=1001-2000,2001-3000&Bodystyle=4dr%20Car,Convertible

#Data i wanted to append

{
  "year": [
    "2017",
    "2018"
  ],
  "model": [
    "Escape",
    "Edge"
  ],
  "mileage": [
    "1-1000"
  ],
  "bodyStyle": [
    "Convertible",
    "4dr Car",
    "2dr Car"
  ],
  "priceRange": [
    "$20,000-$30,000",
    "$30,000-$40,000"
  ]
}
Community
  • 1
  • 1
  • 1
    Why can't you Do pst request with the above son in `req.body`??? – Subburaj Oct 24 '19 at 07:22
  • I think what he is trying to achieve is append those data to the '/new' so that the result would be like new?Year=2020,2019&Pricerange=10001-20000,20001. .... depending on the data – Jhon Caylog Oct 24 '19 at 07:23
  • Have you tried `window.history.pushState('new', 'inventory', '/new?Year=2020,2019&Pricerange=10001-20000,20001-30000,30001-40000&Mileagerange=1001-2000,2001-3000&Bodystyle=4dr%20Car,Convertible')`? Commas in your URL are not part of the `path` component, they are part of the `search` ("query") component, so they are valid. – ahwayakchih Oct 24 '19 at 07:25
  • But i think what he wanted to achived is something dynamic – Jhon Caylog Oct 24 '19 at 07:27
  • @ahwayakchih , dynamic feature – Jhon Caylog Oct 24 '19 at 07:27
  • @ahwayakchih is therea a dynamic way of doing it ? –  Oct 24 '19 at 07:30
  • Are you looking for the `escape` function (or `encodeURIComponent`)? `.pushState('new', 'inv', '/new?Year='+escape("2020,2019"))` – freedomn-m Oct 24 '19 at 07:34
  • BTW `path` component can also contain commas, because `pchar = unreserved / pct-encoded / sub-delims / ":" / "@"` and `sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="`. So `sub-delims` allows comma. – ahwayakchih Oct 24 '19 at 07:35
  • 1
    What you mean by "dynamic"? https://developer.mozilla.org/en-US/docs/Web/API/History/pushState takes whole URL string, so if you want to construct it dynamically you have to write a function that does that based on your format of data. – ahwayakchih Oct 24 '19 at 07:37

2 Answers2

3

jQuery.param() seems to repeat array values, so you'll have to find some existing library or write custom function.

Something like that (but maybe optimized a bit more):

/**
 * Prepare `search` part of URL.
 * @param {object} o Each key is a param name and value is an array of values
 * @return {string}
 */
function createURLQuery (o) {
  return Object.keys(o)
      .map(key => `${encodeURIComponent(key)}=`
          + o[key].map(v => encodeURIComponent(v)).join(','))
      .join('&')
}

// Example code
const data = {
  "year": [
    "2017",
    "2018"
  ],
  "model": [
    "Escape",
    "Edge"
  ],
  "mileage": [
    "1-1000"
  ],
  "bodyStyle": [
    "Convertible",
    "4dr Car",
    "2dr Car"
  ],
  "priceRange": [
    "$20,000-$30,000",
    "$30,000-$40,000"
  ]
};

const newURL = `/new?${createURLQuery(data)}`;

console.log('Pushing new URL', newURL);

// window.history.pushState('new', 'inventory', newURL);

You'll have to implement any additional changes to data yourself. "Desired result" seems to drop "$" characters and capitalize parameter names.

ahwayakchih
  • 2,101
  • 19
  • 24
1

Parse the JSON data to a JS object and parse the keys and values according to your needs. I don't think there's any way to achieve exactly the string format that you want, unless someone wrote a npm package for exactly this case (not deeply nested json object to a query string).

Make use of JSON.parse() and Object.entries() to build a query string based on the JSON input.

I've made an example to have a look at. You still need some parsing for currency and maybe something more.

See below if REPL link wouldn't work.


const json = `
{
  "year": [
    "2017",
    "2018"
  ],
  "model": [
    "Escape",
    "Edge"
  ],
  "mileage": [
    "1-1000"
  ],
  "bodyStyle": [
    "Convertible",
    "4dr Car",
    "2dr Car"
  ],
  "priceRange": [
    "$20,000-$30,000",
    "$30,000-$40,000"
  ]
}`;

const parsedJson = JSON.parse(json);

let queryString = '?';

Object.entries(parsedJson).forEach(([key, value], index) => {
  let string = `${index != 0 ? '&' : ''}${key}=${value.join()}`;
  queryString += string;
});

const encodedQueryString = encodeURIComponent(queryString.trim())
Max
  • 488
  • 8
  • 19