OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

How to make this code an helper to be able to use it everywhere in my app?

  • Thread starter Thread starter Fred Hors
  • Start date Start date
F

Fred Hors

Guest
I'm trying to create an "universal helper" to be used in my Svelte Kit app to be able in a SIMPLE way to persist in the URL the filter conditions of a dashboard or a list so that I can:


  1. return to previous filter settings when I go back and to subsequent ones when I go forward with the browser keys or


  2. save those filters (javascript simple objects with JSON.stringify()) in the browser bookmarks or as a link to share with some people.

I tried with this code (here the reproduction):

Code:
<script>
    let { pagination = { page: 1, size: 10 }, condition = {} } = $props();

    let listInput = $derived({
        pagination: $state.snapshot(pagination),
        condition: $state.snapshot(condition)
    });

    const players = $derived.by(() => {
        return getData(listInput)
    });

    $effect(() => {
        if (!!condition) {
            const url = new URL(window.location.toString());

            const paramCondition = url.searchParams.get('condition');

            const actualCondition = JSON.stringify(condition);

            if (paramCondition !== actualCondition) {
                url.searchParams.set('condition', JSON.stringify(condition));

                goto(url, { replaceState: false, noScroll: true, keepFocus: true });
            }
        }
    });

    afterNavigate(() => {
        const url = new URL(window.location.toString());

        const paramCondition = url.searchParams.get('condition');

        if (paramCondition !== JSON.stringify(condition)) {
            condition = JSON.parse(paramCondition || '{}');
        }
    });
</script>

and it works but I need to repeat the same code for each javascript object I need to save in the URL (not only condition like in this example) and for each page.

Is there a way to make it "universal"?

I tried on a suggestion another way too:

Code:
function syncParams(params: Record<string, any | undefined>) {
    const fromUrl = $derived($page.url.searchParams);

    const retval = {};

    for (let key in params) {
        Object.defineProperty(retval, key, {
            get() {
                console.log('get, key:', key);

                return fromUrl.get(key);
            },
            set(newVal) {
                console.log('set, newVal:', newVal);

                const url = new URL(window.location.toString());
                url.searchParams.set(key, JSON.stringify(newVal));
                goto(url, { replaceState: false, noScroll: true });
            },
            enumerable: true
        });
    }

    return retval;
}

but it doesn't work because my condition can be {} at first and the can be binded like:

Code:
let {
    condition = params.condition,
} = $props();

<input type="text" bind:value={condition.name} />

I'm using Svelte 5 as you can see.

Can you hlep me understand how to do it?

<p>I'm trying to create an "universal helper" to be used in my Svelte Kit app to be able in a SIMPLE way to persist in the URL the filter conditions of a dashboard or a list so that I can:</p>
<ol>
<li><p>return to previous filter settings when I go back and to subsequent ones when I go forward with the browser keys or</p>
</li>
<li><p>save those filters (javascript simple objects with JSON.stringify()) in the browser bookmarks or as a link to share with some people.</p>
</li>
</ol>
<p>I tried with this code (<a href="https://www.sveltelab.dev/84hoezlz83nben0" rel="nofollow noreferrer">here the reproduction</a>):</p>
<pre class="lang-html prettyprint-override"><code><script>
let { pagination = { page: 1, size: 10 }, condition = {} } = $props();

let listInput = $derived({
pagination: $state.snapshot(pagination),
condition: $state.snapshot(condition)
});

const players = $derived.by(() => {
return getData(listInput)
});

$effect(() => {
if (!!condition) {
const url = new URL(window.location.toString());

const paramCondition = url.searchParams.get('condition');

const actualCondition = JSON.stringify(condition);

if (paramCondition !== actualCondition) {
url.searchParams.set('condition', JSON.stringify(condition));

goto(url, { replaceState: false, noScroll: true, keepFocus: true });
}
}
});

afterNavigate(() => {
const url = new URL(window.location.toString());

const paramCondition = url.searchParams.get('condition');

if (paramCondition !== JSON.stringify(condition)) {
condition = JSON.parse(paramCondition || '{}');
}
});
</script>
</code></pre>
<p>and it works but I need to repeat the same code for each javascript object I need to save in the URL (not only <code>condition</code> like in this example) and for each page.</p>
<p>Is there a way to make it "universal"?</p>
<p>I tried on a suggestion another way too:</p>
<pre><code>function syncParams(params: Record<string, any | undefined>) {
const fromUrl = $derived($page.url.searchParams);

const retval = {};

for (let key in params) {
Object.defineProperty(retval, key, {
get() {
console.log('get, key:', key);

return fromUrl.get(key);
},
set(newVal) {
console.log('set, newVal:', newVal);

const url = new URL(window.location.toString());
url.searchParams.set(key, JSON.stringify(newVal));
goto(url, { replaceState: false, noScroll: true });
},
enumerable: true
});
}

return retval;
}
</code></pre>
<p>but it doesn't work because my <code>condition</code> can be <code>{}</code> at first and the can be binded like:</p>
<pre class="lang-html prettyprint-override"><code>let {
condition = params.condition,
} = $props();

<input type="text" bind:value={condition.name} />
</code></pre>
<p>I'm using Svelte 5 as you can see.</p>
<p>Can you hlep me understand how to do it?</p>
 
Top