Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useRouteQuery can only custom deserialize but cannot custom serialize #3970

Open
4 tasks done
matthew-dean opened this issue May 14, 2024 · 4 comments
Open
4 tasks done
Labels
enhancement New feature or request

Comments

@matthew-dean
Copy link

matthew-dean commented May 14, 2024

Clear and concise description of the problem

I stumbled into this because I expected that for sure useRouteQuery would allow deserialization AND serialization transforms in order to store any arbitrary state in the query string.

In my case, I had local refs for startDate and endDate as JavaScript dates. I decided I wanted to persist these dates into the query string. The thing is, useRouteQuery only allows one-way transforms. That is, if I wanted to store the default value as a YYYY-MM-DD, and then deserialize to Date, that seems fine. However, this utility is extremely limited, because I could not control serializing the date BACK into the querystring. (It just defaults to JavaScript's crap date serialization i.e. ?startDate=Mon+Apr+15+2024+14:29:33+GMT-0700+(Pacific+Daylight+Time))

Suggested solution

Allow two-way transforms i.e. serialization. I'd suggest something like:

useRouteQuery(
   'startDate',
    '2024-05-08',
    {
      from(value: string) { // or fromQueryString()? or just transform() how it is now?
        return dayjs(value).toDate()
      }
      to(value: Date) { // or toQueryString()?  or transformTo()?
        return dayjs(value).format('YYYY-MM-DD')
      }
    }

Alternative

I don't see any alternatives immediately, other than using a different library or a drastically different approach.

Additional context

No response

Validations

@matthew-dean matthew-dean added the enhancement New feature or request label May 14, 2024
@matthew-dean matthew-dean changed the title useRouteQuery can only deserialize but cannot serialize useRouteQuery can only custom deserialize but cannot custom serialize May 14, 2024
@matthew-dean
Copy link
Author

Okay, I did think of a workaround right after:

import { useRouteQuery } from '@vueuse/router'
import { dayjs } from './date'
import { computed } from 'vue'

export function useQueryDate(name: string, defaultValue?: Date) {
  const query = useRouteQuery<string | undefined>(
    name,
    defaultValue ? dayjs(defaultValue).format('YYYY-MM-DD') : undefined
  )
  return computed({
    get() {
      return query.value ? dayjs(query.value).toDate() : undefined
    },
    set(value: Date | undefined) {
      query.value = value ? dayjs(value).format('YYYY-MM-DD') : undefined
    }
  })
}

@jpritzkau-eepos
Copy link

Custom serializers already exist in other utilities, such as useStorage. This would also be nice for boolean serialization.

const create = useRouteQuery<boolean>("create", false, {
  serializer: {
    read: (v: string) => v === null,
    write: (v: boolean) => v ? null : undefined
  }
})

create.value = false; // /
create.value = true;  // /?create

@jpritzkau-eepos
Copy link

useStorage even defines default serializers based on the type of the default value. I think that would work well here too.

@jpritzkau-eepos
Copy link

Isn't this a duplicate of #3929?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants