inertiajs / inertia

Inertia.js lets you quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers.
https://inertiajs.com
MIT License
6.3k stars 423 forks source link

Get request data keeps getting appended #1783

Closed timyourivh closed 5 months ago

timyourivh commented 8 months ago

Versions

The problem

What happens is, whenever I call router.reload() with data, the data keeps getting appended to the url instead of being updated/replaced. This causes ridiculously long and invalid urls. This is the second time I encounter this problem, this time in a fresh project. Is this a bug or intended behavior? If so, I will create a feature request (and pr if needed) to change this behavior to be optional.

Reproduction

Setup:

Here is the code that I run:

const loadItems = (params: object): void => {
  router.reload({
    only: ['products'],
    data: params as RequestPayload
  })
}

This function gets called every time something changes in the table like sorting, change page, etc.

Steps:

  1. Visit page: http://localhost/products

  2. Call loadItems: data:

    {"page":1,"itemsPerPage":10,"sortBy":[],"groupBy":[]}

    Resulting URL: http://localhost/products?page=1&itemsPerPage=10

  3. Call loadItems: data:

    {"page":1,"itemsPerPage":10,"sortBy":[{"key":"id","order":"asc"}],"groupBy":[]}

    Resulting URL: http://localhost/products?page=1&itemsPerPage=10&sortBy[][key]=id&sortBy[][order]=asc

  4. Call loadItems: data (notice only sortBy.order changed):

    {"page":1,"itemsPerPage":10,"sortBy":[{"key":"id","order":"desc"}],"groupBy":[]}

    Resulting URL: http://localhost/products?page=1&itemsPerPage=10&sortBy[][key]=id&sortBy[][order]=asc&sortBy[][key]=id&sortBy[][order]=desc

  5. Call loadItems: data:

    {"page":1,"itemsPerPage":10,"sortBy":[],"groupBy":[]}

    Resulting URL: http://localhost/products?page=1&itemsPerPage=10&sortBy[][key][]=id&sortBy[][key][]=id&sortBy[][order][]=asc&sortBy[][order][]=desc

  6. Call loadItems: data (same as in step 3):

    {"page":1,"itemsPerPage":10,"sortBy":[{"key":"id","order":"asc"}],"groupBy":[]}

    Resulting URL: http://localhost/products?page=1&itemsPerPage=10&sortBy[][key][]=id&sortBy[][key][]=id&sortBy[][order][]=asc&sortBy[][order][]=desc&sortBy[][key]=id&sortBy[][order]=asc

  7. Etc.

All goes well until on step 4: the updated parameters don't get replaced/updated and get appended instead from this moment on. This keeps happening and keeps getting appended every change you make. Which ends up in this after clicking the sorting by id a few times: http://localhost/products?page=1&itemsPerPage=10&sortBy[][key][]=id&sortBy[][key][]=id&sortBy[][key][]=id&sortBy[][key][]=id&sortBy[][order][]=asc&sortBy[][order][]=desc&sortBy[][order][]=asc&sortBy[][order][]=desc...

Workaround

One way to work around this, is to clear the url manually every time you reload:

const loadItems = (params: object): void => {
+ history.replaceState({}, document.title, location.pathname)
  router.reload({
    only: ['tenants'],
    data: params as RequestPayload
  })
}

You can also use pushState instead of replaceState depending on what behavior you prefer.

This isn't ideal and causes the url to "flicker", but it works as a good workaround.

peter-emad99 commented 5 months ago

you can do it like this


const withQueryParam = false
 const currentLocation = withQueryParam ? location.href : location.pathname

router.get(currentLocation, { 
preserveState: true,
preserveScroll: true,
 only: ['tenants'],
 data: params as RequestPayload
});
driesvints commented 5 months ago

Hi there,

Thanks for reporting but it looks like this is a question which can be asked on a support channel. Please only use this issue tracker for reporting bugs with the library itself. If you have a question on how to use functionality provided by this repo you can try one of the following channels:

However, this issue will not be locked and everyone is still free to discuss solutions to your problem!

Thanks.

tanogalego commented 4 months ago

I found the same problem. I want to use the router.reload() to make a Partial Reload as stated in the Inertia official docs, but this behavior makes my URL invalid.

In my opinion, Inertial should add a new option to reset the URL on the reload() method when sending new parameters into the data object. I disagree with @driesvints, this looks like a problem caused by a bad design of the Inertia method.

driesvints commented 4 months ago

@tanogalego @timyourivh doesn't the solution from @peter-emad99 help?