Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preserve the query string when using Link or Inertia.get()

Inertia offers a nice way to preserve the state of a component by just adding the "preserve-state" option.

The problem is that, while preserve-state works greate to preserve the form contents, it doesn't seem to keep the query strings.
When the table is filtered and the user clicks on a table head, the filter is being reset because the query string is deleted.

My solution is to call Inertia.get() with all possibly saved query strings. But this doesn't feel very clean and it causes possibly huge repetition.

example

watch(search, (value) => {
    Inertia.get(props.dataUrl, {search: value, orderBy: orderByLocalRef.value, orderDirection: orderDirectionLocalRef.value}, {
        preserveState: true,
        replace: true
    })
})

function orderByClicked(orderKey) {
    if (orderKey) {
        if (orderByLocalRef.value === orderKey)
            orderDirectionLocalRef.value = orderDirectionLocalRef.value === 'asc' ? 'desc' : 'asc';
        else
            orderDirectionLocalRef.value = "asc"

        orderByLocalRef.value = orderKey;

        Inertia.get(props.dataUrl, {search: search.value, orderBy: orderByLocalRef.value, orderDirection: orderDirectionLocalRef.value}, {
            preserveState: true,
            replace: true
        });
    }
}

Is this the best practice to accomplish this or is there a cleaner way?

like image 769
TimSch Avatar asked Sep 12 '25 18:09

TimSch


2 Answers

I've created a Mixin to inherit the query string. It also allows you to inherit and override certain values.

<script>
export default {
    methods: {
        $queryParams(...args) {

            let queryString = this.$page.url;

            if (queryString.indexOf("?") === -1) {
                return {};
            }

            queryString = queryString.substring(queryString.indexOf("?") + 1);
            return Object.assign(Object.fromEntries(new URLSearchParams(queryString)), ...args);
        },
    },
};
</script>

The usage is pretty simple. If you have an inertia Link component or do a manual visit simply append the $queryParams like so:

<Link :href="route('posts.show', { post: post, ...$queryParams() })">
   Show Post
</Link>

If you're current url looks like this:
http://laravel.test/posts/1?view=overview

And you would visit the link to a second post it would automatically inherit the parameters: http://laravel.test/posts/2?view=overview

Sometimes you have a complex query string and want to change only a single parameter on a new page visit. For that you can simply give it an object that will be merged into the string.

Lets say you have this url http://laravel.test/posts/2?view=overview&version=1.0
And now you want to link to a different version of the same post.
For that you would construct your Link like so:

<Link :href="route('posts.show', { post: post, ...$queryParams({ version: '1.1'}) })">
   Show Post
</Link>   

And it would link to http://laravel.test/posts/2?view=overview&version=1.1

like image 157
Robin Reiter Avatar answered Sep 14 '25 12:09

Robin Reiter


I believe ziggy is included with laravel inertia ( although that might be because i used the jetstream start template ) either way, ziggy in laravel gives you the route() helper and it makes it super easy to grab the current url WITH query param by using "route( route().current(), route().params )"

I found this article while searching for this solution then found it elsewhere so thought i'd share.. no need to fuss around with grabbing urls and formatting with "?" and "&=".. Im slapping this badboy on so many forms now

this helps with pagination links, and literally any function call you can make from a page that redirects back to the same page and where you dont want to lose your query-string-provided form field values once redirected

like image 24
Erik White Avatar answered Sep 14 '25 10:09

Erik White