1

So my application atm return this URL without params localhost:3000/website/site1

Params are defined from FRONT component like a calendar modal for params1, for example i choose a date from date picker and it returns me this "2022-11-02" and if i choose a date range with end_date it returns me this "2022-06-25"

So i have localhost:3000/website/site1?start_at=2022-11-02&end_at=2022-06-25

But now i want to add something more

I created a compare website feature, i can compare 2 websites, when i click on this compare button, i need to change the URL and include the compared website, so at the end i want something like this

localhost:3000/website/site1?params1&params2 HERE INCLUDE site2 with same pattern as site1

localhost:3000/website/site1?start_at=2022-11-02&end_at=2022-06-25&site2?start_at=2022-11-02&end_at=2022-06-25

I dont know if the syntax is correct

If this syntax doesnt work how can i make it work ?

And ofc is there is no params value(by default there is none) it should returns this localhost:3000/website/site1&site2

I did this

const compare = {
 start_at: format(new Date(dateRange.start_at), "yyyy-MM-dd"),
 end_at: format(new Date(dateRange.end_at), "yyyy-MM-dd"),
 };
 const compared = {
        start_at: format(
        new Date(dateRangeCompare.start_at),
        "yyyy-MM-dd"),
  end_at: format(new Date(dateRangeCompare.end_at), "yyyy-MM-dd"),
};
const s1 = new URLSearchParams(compare).toString();
const s2 = new URLSearchParams(compared).toString();
const url2 = new URL(window.location.origin);
url2.searchParams.append("site1", s1);
url2.searchParams.append("site2", s2);

but it returns me this http://localhost:3002/?site1=start_at%3D2022-06-21%26end_at%3D2022-06-21&site2=start_at%3D2022-06-21%26end_at%3D2022-06-21

I tried to use decodeURI() on url2 decodeURI(url2) but it doesnt change anything, i tried to do decodeURIcomponent() but it doesnt change anything. I'm lost

TLDR: i want each site (site1 and site2) to have their respective query parameters in URL, site2 need to have the same query pattern as site1

Thanks

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
taranticoscr
  • 35
  • 1
  • 6

1 Answers1

2

When in need of query params with the same name (array-like) use a params format like: ?a[]=1&a[]=2. Just like you would when using checkboxes with the same name or a select of type multiple.

Sites only:

?site[]=x&site[]=y

Sites with dates:

?site[]=x&site[]=y&start_at[]=x1&end_at[]=x2&start_at[]=y1&end_at[]=y2

the only caveat is to respect the order: if you start with site "X", then the first pair of start/end dates should be the ones for site "X".

More readable:

?site[]=x
&site[]=y
&start_at[]=x1
&end_at[]=x2
&start_at[]=y1
&end_at[]=y2

Another valid example with different order:

?site[]=x
&start_at[]=x1
&end_at[]=x2
&site[]=y
&start_at[]=y1
&end_at[]=y2

Then on the back-end side, knowing that the order is predictable, you can get all your variables inside a single loop of sites length.

Also, by using the above suggestion you can use N sites with their respective start/end pairs.

Example:

// Helper functions:

const objectsToFormData = (...objects) => {
  const FD = new FormData();
  objects.forEach(obj => {
    Object.entries(obj).forEach(([k, v]) => FD.append(k, v));
  });
  return FD;
};

const formDataToQueryString = (FD) =>
  new URLSearchParams(FD).toString();

// Task:

const data_1 = {
  "site[]": location.origin,
  "start_at[]": "2022-11-02",
  "end_at[]": "2022-06-25",
};

const data_2 = {
  "site[]": "https://example.com",
  "start_at[]": "2021-09-20",
  "end_at[]": "2022-07-13",
};

const formData = objectsToFormData(data_1, data_2);
const queryString = formDataToQueryString(formData);

console.log(queryString);
console.log(decodeURIComponent(queryString));

Which will give you this Query String:

site%5B%5D=https%3A%2F%2Fstacksnippets.net&start_at%5B%5D=2022-11-02&end_at%5B%5D=2022-06-25&site%5B%5D=https%3A%2F%2Fexample.com&start_at%5B%5D=2021-09-20&end_at%5B%5D=2022-07-13

and if you need the Sites only, the exact same code will work as expected.

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
  • Interesting but how do you make this query string cleaner ? Without the "%5B%5D" for example. Btw what is the purpose of [] notation ? Can you explain it in other terms ? – taranticoscr Jun 21 '22 at 23:54
  • The `[]` notation... see for example: https://stackoverflow.com/a/353423/383904 – Roko C. Buljan Jun 22 '22 at 00:02
  • Is it a problem if i unescape it ? I dont know, it looks messy so i wanted to make it readable – taranticoscr Jun 22 '22 at 00:03
  • Use rather `decodeURIComponent(queryString)` (instead of `unescape`) if you want it to look less messy. I'm not sure exactly about the downsides, but I would use it only for debugging, programmer friendly purposes, and send the escaped (messy) one instead. There are many articles about `unescape`, `decodeURI` and `decodeURIComponent` and their differences if you want to make an indepth research. – Roko C. Buljan Jun 22 '22 at 00:11