To use a German proverb I am standing on the hose....
# javascript
h
To use a German proverb I am standing on the hose. In TanStack Query is there no better way to invalidate a query key than this?
Copy code
val submitHandler = useMutation<CompanyDto?, Error, String, Unit>(
    options = UseMutationOptions(
        mutationFn = {
            secureApi(CompanyEndpoints.putCompany.copy(
                bodySerializerType = typeOf<CompanyDto>(),
                body = editedCompany
            ))
        },
        onSuccess = { _, _, _ ->
            queryClient.invalidateQueries(
                InvalidateQueryFilters<Any,Any,Any, QueryKey>(
                    queryKey = ADMIN_QUERY_KEY
                )
            ) 
        }
    )
)
I kind of hoped the types of
InvalidateQueryFilters
were inferable from
useMutation<...>
. Or am I using it wrong? (Trying to follow this: https://tanstack.com/query/latest/docs/framework/react/examples/auto-refetching?panel=sandbox)
t
Handler is fine
In common case such boilerplate is hidden. You write 1 generic hook and use it in more specific cases
Copy code
val handler = useMyMutation(ADMIN_QUERY_KEY) {
    secureApi(CompanyEndpoints.putCompany.copy(
        bodySerializerType = typeOf<CompanyDto>(),
        body = editedCompany
    ))
}
h
Hey, thanks for the answer! Ok, I just wanted to make sure I do it the right way. I felt like I was overlooking something. Then I will make a wrapper that hides some of the syntax like you said. Thanks.
t
useQuery
,
useMutation
are very generic hooks. Usually you don't use such hooks directly.
h
If someone stumbles over this here is how implemented the helper functions for now:
Copy code
fun <T>useQuery(
    queryKey: QueryKey,
    initialData: T? = null,
    queryFunction: () -> PromiseResult<T?>
): UseQueryResult<T, Error> =
    useQuery<T?, Error, T, QueryKey>(
        options = UseQueryOptions(
            queryKey = queryKey,
            initialData = initialData?.let { {initialData} },
            queryFn = QueryFunction { queryFunction() }
        )
    )

fun <T>useMutation(
    mutateFunction: (String) -> Promise<T>,
    onSuccess: QueryClient.(T) -> Promise<*>,
): UseMutationResult<T, Error, String, Unit> =
    with(useQueryClient()) {
        useMutation<T, Error, String, Unit>(
            options = UseMutationOptions(
                mutationFn = mutateFunction,
                onSuccess = { data, _, _ ->
                    onSuccess(data)
                }
            )
        )
    }

fun <T>UseMutationResult<T, Error, String, Unit>.mutate(block: (T) -> Unit) =
    mutate("", MutateOptions(
        onSuccess = { data, _, _ ->
            block(data)
        }
    ))

fun QueryClient.invalidateQueryKey(queryKey: QueryKey): Promise<*> =
    invalidateQueries(
        InvalidateQueryFilters<Any,Any,Any, QueryKey>(
            queryKey = queryKey
        )
    )
And how I use it:
Copy code
val companyQuery = useQuery(ADMIN_QUERY_KEY, loaderData) {
    secureApi(CompanyEndpoints.getCompany)
}

val handleSubmit = useMutation(
    mutateFunction = { secureApi(CompanyEndpoints.putCompany.copy(
        bodySerializerType = typeOf<CompanyDto>(),
        body = editedCompany
    ))},
    onSuccess = {
        invalidateQueryKey(queryKey = ADMIN_QUERY_KEY)
    }
)

[...]

Button {
    variant = ButtonVariant.contained
    color = ButtonColor.primary
    onClick = { handleSubmit.mutate {
        handleGoBack()
    }}
    disabled = company.name.isEmpty()
    +"save".intl()
}