2
\$\begingroup\$

I need all the below code to be able to persist in the URL (query string) some variables I'm using in a Svelte 5 / Svelte Kit project page.

I also need to assign URL query params to variables on page reload or page change.

As you can see, the code is very repetitive, and I think there must be a better way (better = DRY and faster).

I created a small reproduction.

What do you think?

// condition, pagination and searchText comes from $props()
let firstLoad = $state(true);
$effect(() => {
 if (firstLoad) return;
 const url = new URL(window.location.toString());
 const paramCondition = url.searchParams.get('condition');
 const paramPagination = url.searchParams.get('pagination');
 const paramSearchText = url.searchParams.get('searchText');
 const actualCondition = isAnEmptyOrFalsyObject(condition) ? null : JSON.stringify(condition);
 const actualPagination = isAnEmptyOrFalsyObject(pagination) ? null : JSON.stringify(pagination);
 const actualSearchText = !searchText ? null : searchText;
 let shouldGo = false;
 if (paramCondition !== actualCondition) {
 if (actualCondition) {
 url.searchParams.set('condition', actualCondition);
 } else {
 url.searchParams.delete('condition');
 }
 shouldGo = true;
 }
 if (paramPagination !== actualPagination) {
 if (actualPagination) {
 url.searchParams.set('pagination', actualPagination);
 } else {
 url.searchParams.delete('pagination');
 }
 shouldGo = true;
 }
 if (paramSearchText !== actualSearchText) {
 if (actualSearchText) {
 url.searchParams.set('searchText', actualSearchText);
 } else {
 url.searchParams.delete('searchText');
 }
 shouldGo = true;
 }
 if (shouldGo) goto(url, { replaceState: false, keepFocus: true, noScroll: true });
});
afterNavigate(({ to }) => {
 if (!to) return;
 const paramCondition = to.url.searchParams.get('condition');
 const paramPagination = to.url.searchParams.get('pagination');
 const paramSearchText = to.url.searchParams.get('searchText');
 if (paramCondition && paramCondition !== JSON.stringify(condition)) {
 condition = JSON.parse(paramCondition);
 }
 if (paramPagination && paramPagination !== JSON.stringify(pagination)) {
 pagination = JSON.parse(paramPagination);
 }
 if (paramSearchText && paramSearchText !== searchText) {
 searchText = paramSearchText;
 }
 if (firstLoad) firstLoad = false;
});
toolic
14.6k5 gold badges29 silver badges204 bronze badges
asked Jul 10, 2024 at 14:37
\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

extract helper

For each of condition, pagination, and search text you apply the identical logic. So create a boolean helper that implements the desired side effects. And keep ORing its result into your flag. (I probably would have named it want_redirect, but whatever.)

extra test

Three times you do this sort of thing:

 if (paramCondition && paramCondition !== JSON.stringify(condition)) {
 condition = JSON.parse(paramCondition);
 }

That second conjunct looks like a premature optimization. Does .parse() really cost so much that we're willing to clutter the code with an extra .stringify() to avoid it? I say that once we know we have a condition parameter, just unconditionally parse and assign it, to make the code more concise.

answered Jul 10, 2024 at 17:32
\$\endgroup\$
1
  • \$\begingroup\$ Thank you very much. The second part is brilliant. Thanks! I'm a bit in doubt about the first (extract helper). Can you write a small example of what you mean? \$\endgroup\$ Commented Jul 14, 2024 at 12:25

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.