Intevel / nuxt-directus

🐰 Easily integrate Directus to your Nuxt application.
https://nuxt-directus.de/
MIT License
269 stars 49 forks source link

Problems comparing result of `useDirectusUser` with result from async item fetch #253

Closed KB1RD closed 7 months ago

KB1RD commented 7 months ago

Version

nuxt-directus ^5.6.1 nuxt: ^3.11.1

Reproduction Link

I cannot share my entire codebase at this time; Below is the segment of code causing the issue:

...
const user = useDirectusUser();

const { getItemById } = useDirectusItems();
...
const fetchProfile = async (id) => {
  const data = await getItemById({ collection: "Profiles", id, params });

  console.log("User:", user);
  // First try comparing these values 
  console.log("COMPUTE1", user.id, data.Owner); // Prints `COMPUTE1 undefined 51011f11-09df-49fd-82db-4f155870556f` on server

  return data;
};

const {
  data,
  error,
  pending,
} = await useAsyncData(`profiles:${profile_id}`, () => fetchProfile(profile_id));

// See what is in `data` after that last async runs
console.log("COMPUTE2", user.id, data.Owner); // Prints `COMPUTE2 undefined undefined` on server and client

// Perhaps a computed property will work?
const is_owner = computed(() => {
  console.log("COMPUTE3", user.id, data.Owner); // Prints `COMPUTE3 undefined undefined` on server and client
  return user.id == data.Owner;
});

Steps to reproduce

  1. Set up the basic authentication example
  2. On an authenticated page, load some content and try to compare a field (in this case, Owner) in this content to the current user's ID using various methods (see the code sample above). Note that in my case, this getItemById function actually will fail with HTTP 403 if the user is not signed in, so in this function call, the user ID must be known somewhere in nuxt-directus.

What is Expected?

At the very least, the print statement labelled COMPUTE1 should print out both user ids, instead of undefined for user.id. It is definitely accessible in that code block, since the above statement relies on having the user currently signed in.

What is actually happening?

In all of the above examples, user.id evaluates to undefined. What is especially weird is that the print statement labeled "User:" prints the following:

ObjectRefImpl {
  _object:
   { '$s__nuxt_devtools__': { timeSsrStart: 1711757285834 },
     '$sdirectus.user':
      { id: '5daecae4-1625-47ad-89f5-678c36531dcc',
        first_name: 'Test',
        last_name: 'User',
        email: 'test@example.com',
        password: '**********',
        location: null,
        title: null,
        description: null,
        tags: [Array],
        avatar: null,
        language: null,
        tfa_secret: null,
        status: 'active',
        role: 'a1f88c5d-0c58-44f0-9f24-ef2df053d786',
        token: null,
        last_access: '2024-03-29T23:53:12',
        last_page: '/content/Profiles',
        provider: 'default',
        external_identifier: null,
        auth_data: null,
        email_notifications: true,
        appearance: null,
        theme_dark: null,
        theme_light: null,
        theme_light_overrides: null,
        theme_dark_overrides: null,
        Profile: null } },
  _key: '$sdirectus.user',
  _defaultValue: undefined,
  __v_isRef: true }

So Nuxt knows about the user object, knows its ID, but doesn't want to share. The workaround that I am currently using is:

const userpatch = user?._object["$sdirectus.user"] || user;

...to obtain the user object. But this is not a long-term solution.

KB1RD commented 7 months ago

Note: Putting const user = useDirectusUser(); in the async function before calling getItemById also does not work.

vaddenz commented 7 months ago

Hi @KB1RD, have you tried accessing the user's attributes via user.value (according to this sample)?

KB1RD commented 7 months ago

My apologies; I used Vue years ago, and have been trying to familiarize myself with Vue 3. Seems I need to go through the whole docs and re-learn from scratch as there are so many "gotchas" for someone familiar with old versions of Vue.