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¶ms2 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=2022-06-21&end_at=2022-06-21&site2=start_at=2022-06-21&end_at=2022-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
CodePudding user response:
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);
Which will give you this Query String:
site[]=https://stacksnippets.net&start_at[]=2022-11-02&end_at[]=2022-06-25&site[]=https://example.com&start_at[]=2021-09-20&end_at[]=2022-07-13
and if you need the Sites only, the exact same code will work as expected.