Skip to content

[queryParamsStore] enhancements #37

Open

Description

@frederikhors

Since your project is AMAZING, I was wondering what do you think about creating a "kit for Kit" with Svelte 5 that allows us to save in the page URL any POJO object or scalar type we need with the serializer we need (for example I can use JSON.stringify() and JSON.parse() for now).

I described something similar here.

This would be amazing for lists filters for example:

  1. I have a players list on page /players

  2. I order the list by created_at DESC

  3. the kit saves this filter in the URL: /players?order_by=created_at_DESC (just an example)

  4. I filter players form team_id: 123

  5. the kit saves this new filter in the URL: /players?order_by=created_at_DESC&team_id=123 (just an example)

  6. I go back with the browser and the URL is now again: /players?order_by=created_at_DESC (just an example)

  7. I reload the page now and since the URL is this the list is ordered like before the reload

I hope you get the idea.

I now can manually add this using in each place I need it url.searchParams.set and afterNavigate but I would like to have an helper to be used everywhere.

Again, thanks for your work!

Activity

  1. techniq commented on Jul 9, 2024

    @techniq
    Owner

    Thanks for the kinds words @frederikhors 😊.

    If I'm understanding correctly, It sounds like what you are looking for is query string management with different strategies. Svelte UX has queryParamsStore (manage multiple params) as well as queryParamStore (single param) with different types/strategies. There is a pretty robust test suite and docs to see the differences, but maybe I'm misunderstanding what you are looking for.

    @paoloricciuti also has the wonderful https://github.com/paoloricciuti/sveltekit-search-params which I haven't looked closely at yet, but I think it's similar and likely has better SvelteKit integration (I created queryParamsStore for SPAs before SvelteKit existed)

  2. frederikhors commented on Jul 10, 2024

    @frederikhors
    Author

    Thanks for your answer.

    I tried queryParamsStore and it works good (thanks again for your work!) but does not all I need.

    I created a small reproduction: see the file /svelte-ux/+page.svelte:

    1. since I'm using new Svelte 5's $props() I'm assigning:

      const filters = queryParamsStore({
        defaults: {
          condition: {},
          searchText: undefined,
        },
        paramTypes: (key) => {
          switch (key) {
            case "condition":
              return "object";
            case "searchText":
              return "string";
          }
        },
        page,
        goto,
      });
      
      let { pagination = { page: 1, size: 10 }, condition = $filters.condition } = $props();

      and obviously if I assign something to condition.name = "bob" it doesn't work

    2. I cannot assign to $filters.condition neither

    3. The same goes with searchText (simple string): if I assign it as default props value and I bind it with an input it doesn't work

    These are very useful features especially with Svelte 5.

    I'm already talking with @paoloricciuti here about this.

  3. techniq commented on Jul 10, 2024

    @techniq
    Owner

    Thanks for the added context and discussion. If i understand the problem you want:

    • Fine-grained reactivity (for each param) with the ability to bind each parameters, including nested properties (ex. condition.name or pagination.page
    • You want to set an initial default value (constant) or default to a props value, but will be overridden by the query param value when set, but used anytime it is not defined in the query string.

    You MIGHT be able to use queryParamStore for each parameter (and thus a store for each) instead of managing all params with a single queryParamsStore.

    I haven't tried testing this and rather buried with other tasks ATM. I plan to migrate all Svelte UX stores to Svelte 5 with runes but it will take some time.

    import { queryParamsStore } from 'svelte-ux';
    import { page } from '$app/stores';
    import { goto } from '$app/navigation';
    
    let { pagination, condition } = $props();
    
    const paginationParam = queryParamStore({
      name: 'pagination',
      default: pagination ?? { page: 1, size: 10 },
      paramType: 'object',
      page,
      goto,
    });
    
    const conditionParam = queryParamStore({
      name: 'condition',
      default: condition,
      paramType: 'object',
      page,
      goto,
    });
    
    <input type="text" bind:value={$conditionParam.name} />
  4. techniq commented on Jul 10, 2024

    @techniq
    Owner

    I did try to update your SvelteLab example with the following...

    <script>
    	import { queryParamStore } from 'svelte-ux';
    
    	import { afterNavigate, goto } from '$app/navigation';
    	import { page } from '$app/stores';
    
    	import { getData } from '../db.ts';
    
    	let { pagination, condition } = $props();
    
    	const paginationParam = queryParamStore({
    	  name: 'pagination',
    	  default: pagination ?? { page: 1, size: 10 },
    	  paramType: 'object',
    	  page,
    	  goto,
    	});
    	
    	const conditionParam = queryParamStore({
    	  name: 'condition',
    	  default: condition ?? {},
    	  paramType: 'object',
    	  page,
    	  goto,
    	});
    
    	let listInput = $derived({
    		pagination: $paginationParam,
    		condition: $conditionParam
    	});
    
    	const players = $derived.by(() => {
    		return getData(listInput);
    	});
    </script>
    
    condition: {JSON.stringify($conditionParam)}
    
    <br /><br />
    
    Search player by name:
    
    <input type="text" bind:value={$conditionParam.name} />
    
    <br /><br />
    
    {#each players as player}
    	name: {player.name} - gender: {player.gender} <br /><br />
    {/each}

    but it didn't work

    image

  5. changed the title [-]Just an idea[/-] [+][queryParamsStore] enhancements[/+] on Jul 10, 2024
  6. frederikhors commented on Jul 10, 2024

    @frederikhors
    Author

    I will try in a moment. I think pushState() has a bug and needs setTimeout for now.

    But in the meantime, I opened sveltejs/kit#12460 right now.

    That code works (not so performant or good) but is very repetitive, but it's a start for me.

    Do you think the code you posted can do the same?

  7. techniq commented on Jul 10, 2024

    @techniq
    Owner

    TBH I'm not sure. queryParamStore does not use Svelte 5 $effect and just calls goto from $app/navigation based on store.set being called.

  8. frederikhors commented on Jul 10, 2024

    @frederikhors
    Author

    I updated https://www.sveltelab.dev/4vnxej0ewwtlwe9?files=.%2Fsrc%2Froutes%2Fsvelte-ux%2F%2Bpage.svelte.

    Condition is not persisted in the URL at all.

    😢

  9. techniq commented on Jul 10, 2024

    @techniq
    Owner

    I updated https://www.sveltelab.dev/4vnxej0ewwtlwe9?files=.%2Fsrc%2Froutes%2Fsvelte-ux%2F%2Bpage.svelte.

    Condition is not persisted in the URL at all.

    😢

    Look in your console 😉. This was the error I was referring to.

    image

  10. frederikhors commented on Jul 10, 2024

    @frederikhors
    Author

    You're right. I don't know what to do.

    I'm shocked that I haven't found anything similar to what I need anywhere on the web and yet it's something that should be very useful to a lot of people!

  11. techniq commented on Jul 10, 2024

    @techniq
    Owner

    I think rolling something custom like you have in sveltejs/kit#12460 is your best choice right now.

    Svelte UX's plan for Svelte 5 is to get it compatible with Svelte 3-5 which is helping to tease out some Svelte 5 regressions. I'm fairly close on getting the full docs running on Svelte 5 (it does locally, but currently fails some svelte-check and I had to remove sveld generated API docs until I find a solution). I think the root issue is the AST changing. I'm considering parsing the AST myself, but just haven't found the bandwidth. There are some additional regressions I've seen while using the docs locally I need to identify a small reproduction and report as well. Migrating the LayerChart docs to Svelte 5 is also a priority.

    I already have Github Analysis and Strava Analysis running on Svelte 5, but know there is at least an issue with DateRangeField in some cases I need to investigate / report.

    image

    LayerChart's simplified charts is my current priority when I have time for open source, which ebbs and flows.

  12. transferred this issue fromtechniq/svelte-uxon Mar 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions