Closed m-anwr closed 2 months ago
I've also experienced this and have written a workaround. Just pass your AsyncData object to useUncachedData()
. Using a custom key is required to ensure consistency.
import type { AsyncData } from "#app";
const CACHE_KEY_PREFIX = "$apiParty";
type Keys = MaybeRefOrGetter<string | string[]> | MaybeRefOrGetter<string>[];
/**
* Modifies an `AsyncData` object's `refresh` method so it ignores the cache
* when called.
*
* The `key` parameter must be the same as passed to the `key` option in
* `useApiData()`.
*
* @param keyRef The cache key used in `useApiData()`
* @param data The AsyncData result from `useApiData()`
*
* @example
* ```ts
* const { data, refresh } = useUncachedData(
* "myKey",
* useApiData("some/path", {
* key: "myKey"
* }),
* )
* ```
*/
export function useUncachedData<Data, Error>(keyRef: Keys, data: AsyncData<Data, Error>) {
const keys = computed(() => {
const keys = toValue(keyRef);
if (Array.isArray(keys)) {
return keys.map(useCacheRef);
}
return [useCacheRef(keys)];
});
// make refresh ignore the cache
const { refresh } = data;
const refreshInvalidate: typeof refresh = async (opts) => {
// invalidate the cache
for (const key of keys.value) {
key.value = undefined;
}
return await refresh(opts);
};
data.refresh = refreshInvalidate;
// awaiting gets the original asyncdata object, which is separate from the Promise
data.then((asyncData) => {
asyncData.refresh = refreshInvalidate;
});
return data;
}
export function useCacheRef<T = unknown>(key: MaybeRefOrGetter<string>) {
const nuxt = useNuxtApp();
return computed<T | undefined>({
get: () => nuxt.payload.data[CACHE_KEY_PREFIX + toValue(key)],
set: (value) => {
if (value === undefined) {
delete nuxt.payload.data[CACHE_KEY_PREFIX + toValue(key)];
} else {
nuxt.payload.data[CACHE_KEY_PREFIX + toValue(key)] = value;
}
},
});
}
With the latest Nuxt versions, you can use the clear
function provided in the async data object to clear the fetched data and refetch afterwards:
const { data, refresh, clear } = await useApiData("posts")
async function invalidateAndRefresh() {
clear()
await refresh()
}
Environment
Reproduction
Describe the bug
When the Refresh button is clicked, the API is not called and the cached result is returned. Is that the expected behavior? I can't find any reference for that in the docs.
A workaround would be to use a custom cache key and change it if I wanted to refresh the content. otherwise, I have to set the cache to
false
Additional context
No response
Logs
No response