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

Data is refetched when using same key in useAsyncData on client side navigation #19027

Closed
MikeBellika opened this issue Feb 14, 2023 · 4 comments

Comments

@MikeBellika
Copy link
Contributor

Environment

Stackblitz

Reproduction

https://stackblitz.com/edit/github-bqbjuq?file=pages%2Ftest1.vue,pages%2Findex.vue
Navigate back and forth between test1 and index and notice new random numbers.

Describe the bug

When using useAsyncData with a static key, I would expect data to only be fetched once. However when navigating back and forth, useAsyncData is called repeatedly.

I would expect the data to stay the same when the key is the same.
I have implemented my useAsyncData like so:

const { data, refresh } = useAsyncData('test', async () => {
  const number = Math.random();
  await new Promise((r) => setTimeout(r, 10));
  console.log({ number });
  return [...(data.value ?? []), [number]];
});

The reason I use the existing data.value is so we can load more data, when a user requests more. In this case by clicking a button. We use this pattern for pagination.

Oddly enough this doesn't happen when nothing is awaited in useAsyncData.

Another possibly unrelated bug is that the component crashes silently, when data is access before anything is awaited.
So this crashes:

const { data, refresh } = useAsyncData('test', async () => {
  const number = Math.random();
  console.log({data})
  await new Promise((r) => setTimeout(r, 10));
  console.log({ number });
  return [...(data.value ?? []), [number]];
});

and this doesn't:

const { data, refresh } = useAsyncData('test', async () => {
  const number = Math.random();
  await new Promise((r) => setTimeout(r, 10));
  console.log({data})
  console.log({ number });
  return [...(data.value ?? []), [number]];
});

Additional context

No response

Logs

No response

@danielroe
Copy link
Member

I think we can track in #15445 - this was a change before release so data isn't cached by default unless you have enabled payload extraction.

@danielroe danielroe closed this as not planned Won't fix, can't repro, duplicate, stale Feb 14, 2023
@MikeBellika
Copy link
Contributor Author

I think we can track in #15445 - this was a change before release so data isn't cached by default unless you have enabled payload extraction.

@danielroe Thank you for the quick reply. Is there another issue on the silent crash when accessing data before await?

@danielroe
Copy link
Member

danielroe commented Feb 14, 2023

All asyncData errors are silent - you need to check the error object that's returned from useAsyncData.

But I can't reproduce the one you mention. So maybe create a minimal reproduction and create a new issue specific to that?

edit: just saw you provided a stackblitz - checking that

edit: no, I can't reproduce

@MikeBellika
Copy link
Contributor Author

All asyncData errors are silent - you need to check the error object that's returned from useAsyncData.

But I can't reproduce the one you mention. So maybe create a minimal reproduction and create a new issue specific to that?

edit: just saw you provided a stackblitz - checking that

edit: no, I can't reproduce

Error is

Error: Cannot access 'data' before initialization

Which makes sense, however I would expect to also get this error when using data after await. I used this to get the error:

<template>
  <div>
    <NuxtLink to="/test1">Go to test1</NuxtLink><br /><br />
    <button @click="loadMore">Load more</button><br />
    {{ error }}
    <ul>
      <li v-for="number in data">{{ number }}</li>
    </ul>
  </div>
</template>
<script setup lang="ts">
const { data, refresh, error } = useAsyncData('test', async () => {
  const number = Math.random();
  console.log({ data });
  await new Promise((r) => setTimeout(r, 10));
  console.log({ number });
  return [...(data.value ?? []), [number]];
});

const loadMore = () => {
  refresh();
};
</script>

Changing it to

<template>
  <div>
    <NuxtLink to="/test1">Go to test1</NuxtLink><br /><br />
    <button @click="loadMore">Load more</button><br />
    {{ error }}
    <ul>
      <li v-for="number in data">{{ number }}</li>
    </ul>
  </div>
</template>
<script setup lang="ts">
const { data, refresh, error } = useAsyncData('test', async () => {
  const number = Math.random();
  await new Promise((r) => setTimeout(r, 10));
  console.log({ data });
  console.log({ number });
  return [...(data.value ?? []), [number]];
});

const loadMore = () => {
  refresh();
};
</script>

fixes the error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants