OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Why is Vue's Composable not Isolated?

  • Thread starter Thread starter Egy Ramschie
  • Start date Start date
E

Egy Ramschie

Guest
I'm using Vue 3 with Nuxt 3 and Vite, and I'm encountering a strange bug. It occurs almost everywhere in my app whenever I try to use useFetch within a composable.

For example, I have the following composable to check whether a button can be rendered based on the user's role:

useCheckerRole Composable​


Code:
export function useCheckerRole(policies){
  const {data, error} = await useFetch("/api/role-checker", {
    method: "POST",
    body: policies
  })

  if(data.value) {
    return data.value
  }

  if(error.value) {
    throw new Error("an error occured");
  }
}

I then need to pass the policies like so whenever I need to check their roles.

Code:
const policies = await useCheckerRole([
  {
   component_ask: 'some-button',
   role_ask: 'administrator'
  }
])

which then returns something like this from the api:

Code:
  [{
   component_ask: 'some-button',
   role_ask: 'administrator',
   status: 'approved'
  }]

The Bug​


The bug shows up when I mount useCheckerRole in two different components on the same page.

For instance, in my topbar component, I use the useCheckerRole to determine if a specific button or menu should be displayed, depending on the user's role. Meanwhile, elsewhere on the page, I have another button that requires similar role-based checking.

TopBar.vue​


The topbar sends this to the role checker and then immediately logs the result

Code:
const policies = await useCheckerRole([
  {
   component_ask: 'top-bar-button',
   role_ask: 'administrator'
  }
]).catch((error)....)

console.log("topBar Policies result", policies)

ChildPage.vue​


The child page sends this to the useCheckerRole and immediately logs the result

Code:
const policies = await useCheckerRole([
  {
   component_ask: 'child-page-button',
   role_ask: 'administrator'
  },
  {
   component_ask: 'child-page-other-button',
   role_ask: 'administrator'
  },
]).catch((error)....)

console.log("Child Policies result", policies)

TopBar.vue Result​


now the result of the Topbar is interestingly this:

🐞 What TopBar got​


Code:
[
  {
   component_ask: 'child-page-button',
   role_ask: 'administrator',
   status: "approved"
  },
  {
   component_ask: 'child-page-other-button',
   role_ask: 'administrator',
   status: "rejected"
  },
]

Notice that this was not what the Topbar component sent to the useCheckerRole, rather this was what the ChildPage sent.

✅ What TopBar should've gotten​


Code:
[
  {
   component_ask: 'top-bar-button',
   role_ask: 'administrator',
   status: "approved"
  },
]

The ChildPage also got the same result as the Topbar:

Code:
[
  {
   component_ask: 'child-page-button',
   role_ask: 'administrator',
   status: "approved"
  },
  {
   component_ask: 'child-page-other-button',
   role_ask: 'administrator',
   status: "rejected"
  },
]

This made me realize that composables are not as isolated as I thought when using useFetch, or maybe I'm doing something very wrong. Because it looks like both component were calling to the same unisolated function at the same time even if said function are supposed to be isolated.

The initial result in TopBar was correct. However, when ChildPage also called the same function, it somehow overrode the result, which unfortunately wasn't what TopBar asked for.

Does anyone else have this issue?

<p>I'm using Vue 3 with Nuxt 3 and Vite, and I'm encountering a strange bug. It occurs almost everywhere in my app whenever I try to use useFetch within a composable.</p>
<p>For example, I have the following composable to check whether a button can be rendered based on the user's role:</p>
<h2>useCheckerRole Composable</h2>
<pre class="lang-js prettyprint-override"><code>export function useCheckerRole(policies){
const {data, error} = await useFetch("/api/role-checker", {
method: "POST",
body: policies
})

if(data.value) {
return data.value
}

if(error.value) {
throw new Error("an error occured");
}
}
</code></pre>
<p>I then need to pass the policies like so whenever I need to check their roles.</p>
<pre class="lang-js prettyprint-override"><code>const policies = await useCheckerRole([
{
component_ask: 'some-button',
role_ask: 'administrator'
}
])

</code></pre>
<p>which then returns something like this from the api:</p>
<pre class="lang-js prettyprint-override"><code> [{
component_ask: 'some-button',
role_ask: 'administrator',
status: 'approved'
}]
</code></pre>
<h2>The Bug</h2>
<p>The bug shows up when I mount useCheckerRole in two different components on the same page.</p>
<p>For instance, in my topbar component, I use the useCheckerRole to determine if a specific button or menu should be displayed, depending on the user's role. Meanwhile, elsewhere on the page, I have another button that requires similar role-based checking.</p>
<h3>TopBar.vue</h3>
<p>The topbar sends this to the role checker and then immediately logs the result</p>
<pre class="lang-js prettyprint-override"><code>const policies = await useCheckerRole([
{
component_ask: 'top-bar-button',
role_ask: 'administrator'
}
]).catch((error)....)

console.log("topBar Policies result", policies)
</code></pre>
<h3>ChildPage.vue</h3>
<p>The child page sends this to the useCheckerRole and immediately logs the result</p>
<pre class="lang-js prettyprint-override"><code>const policies = await useCheckerRole([
{
component_ask: 'child-page-button',
role_ask: 'administrator'
},
{
component_ask: 'child-page-other-button',
role_ask: 'administrator'
},
]).catch((error)....)

console.log("Child Policies result", policies)
</code></pre>
<h2>TopBar.vue Result</h2>
<p>now the result of the Topbar is interestingly this:</p>
<h3>🐞 What TopBar got</h3>
<pre class="lang-js prettyprint-override"><code>[
{
component_ask: 'child-page-button',
role_ask: 'administrator',
status: "approved"
},
{
component_ask: 'child-page-other-button',
role_ask: 'administrator',
status: "rejected"
},
]
</code></pre>
<p>Notice that this was not what the Topbar component sent to the useCheckerRole, rather this was what the ChildPage sent.</p>
<h3>✅ What TopBar should've gotten</h3>
<pre class="lang-js prettyprint-override"><code>[
{
component_ask: 'top-bar-button',
role_ask: 'administrator',
status: "approved"
},
]
</code></pre>
<p>The ChildPage also got the same result as the Topbar:</p>
<pre class="lang-js prettyprint-override"><code>[
{
component_ask: 'child-page-button',
role_ask: 'administrator',
status: "approved"
},
{
component_ask: 'child-page-other-button',
role_ask: 'administrator',
status: "rejected"
},
]
</code></pre>
<p>This made me realize that composables are not as isolated as I thought when using useFetch, or maybe I'm doing something very wrong. Because it looks like both component were calling to the same unisolated function at the same time even if said function are supposed to be isolated.</p>
<p>The initial result in TopBar was correct. However, when ChildPage also called the same function, it somehow overrode the result, which unfortunately wasn't what TopBar asked for.</p>
<p>Does anyone else have this issue?</p>
 

Latest posts

Online statistics

Members online
0
Guests online
4
Total visitors
4
Top