Search code examples
vue.jsnuxt.jsnuxt3.js

Why does useLazyFetch composable returns null data?


I am trying to learn how to use the data fetching composables in Nuxt3. For some reason, I get a "loading" text in place of where the username should be:

enter image description here

My expected output is supposed to be something like:

enter image description here

Stackblitz demo: https://stackblitz.com/edit/nuxt-starter-grcyfr?file=components/PostCard.vue

Here's my composable code: useUser:

export default function (id) {
  const baseURL = 'https://jsonplaceholder.typicode.com';
  const { pending: pendingUsers, data: users } = useLazyFetch(
    `${baseURL}/users`
  );
  const { pending: pendingUser, data: user } = useLazyFetch(
    `${baseURL}/users/${id}`
  );

  return {
    pendingUsers,
    users,
    pendingUser,
    user,
  };
}

And the component where I want to use it is here: PostCard.vue:

<template>
  <article class="rounded border overflow-hidden">
    ...snip...
      <footer class="mt-6 flex items-center">
        <PostAvatar :post="post" />
        <div class="ml-3">
          <p class="text-sm font-medium text-gray-900">
            <a href="#" class="hover:underline">
              {{ pendingUser ? 'Loading...' : user.name }} /////<---- HERE!
            </a>
          </p>
          <div class="flex space-x-1 text-sm text-gray-500">
            <!-- <time :datetime="post.datetime">
              {{ post.date }}
            </time> -->
            mar 4, 2019
            <span aria-hidden="true">&middot;</span>
            <span>misc</span>
          </div>
        </div>
      </footer>
    ...snip...
  </article>
</template>

<script setup>
const props = defineProps({
  post: {
    type: Object,
    default: () => ({}),
  },
});
const { pendingUser, user } = useUser(props.post.userId);
</script>

Anyone know why the username is not loading? If I console.log(pendingUser.value, user.value) I get true null


Solution

  • Update

    Not sure if it's an actual current issue but downgrading nuxt to 3.0.0-rc.1 fixed the issue.


    Given this composable

    /composables/useUser.js

    export default (id) => {
      const baseURL = 'https://jsonplaceholder.typicode.com';
    
      const { pending: pendingUser, data: user } = useLazyFetch(
        `${baseURL}/users/${id}`
      );
      return {
        pendingUser,
        user,
      };
    }
    

    And this view

    /pages/index.vue

    <script setup>
    const { pendingUser, user } = useUser(2);
    
    watch(user, (newUser) => {
      console.log('newUser', newUser);
      user.value = newUser;
    })
    </script>
    
    <template>
      <div>
        <div>pending? {{ pendingUser }}</div>
        <pre>{{ pendingUser ? 'loading' : user }}</pre>
      </div>
    </template>
    

    You should have something working.

    The usage of watch may be needed (not sure) as explained in the documentation because useLazyFetch is async and non-blocking.