nuxt-authorization icon indicating copy to clipboard operation
nuxt-authorization copied to clipboard

bouncer execute twice

Open d-o0o-b opened this issue 1 year ago • 14 comments

<script setup lang="ts">
import {defineAbility} from "nuxt-authorization/utils";

const testAbility = defineAbility((user) => {
  console.log(user)
  return true
})
</script>

<template>
  <Bouncer :ability="testAbility">
    <template #can>1</template>
    <template #cannot>2</template>
  </Bouncer>
</template>

<style scoped>

</style>

when I refresh page:

image

export default defineNuxtConfig({
  compatibilityDate: '2024-04-03',
  devtools: { enabled: true },
  modules: ['nuxtjs-naive-ui', '@nuxt/icon', '@prisma/nuxt', 'nuxt-authorization'],
  ssr: false
})

d-o0o-b avatar Oct 19 '24 00:10 d-o0o-b

@d-o0o-b I did not check, but could it be because you declared the ability in a script setup? I would suggest you to define it in the shared folder :)

zAlweNy26 avatar Nov 22 '24 16:11 zAlweNy26

Nop, this is because of the watchEffect that runs on the server and on the client. This could be solved with a useState to avoid to rerun the ability.

Barbapapazes avatar Nov 22 '24 20:11 Barbapapazes

@Barbapapazes Should we close this issue?

Psycarlo avatar Jun 23 '25 00:06 Psycarlo

useState

hi Barbapapazes.I encountered the issue of requests being sent twice today while testing nuxt-authorization, but I'm not sure how to resolve it based on your answer. Could you please provide a clear and easy-to-understand solution for reference? I believe I'm certainly not the only one who doesn't know how to handle this tricky problem. thinks

lanwu114 avatar Sep 10 '25 01:09 lanwu114

@lanwu114 https://nuxt.com/docs/4.x/api/composables/use-state Check the docs or send your code example

Psycarlo avatar Sep 10 '25 01:09 Psycarlo

<script setup lang="ts">
import { defineAbility } from 'nuxt-authorization/utils'

const createProduct = defineAbility(() => {
  console.log('createProduct')
  return true
})

</script>

<template>
        <Can :ability="createProduct">
          <UButton @click="test">
            看得到吗?
          </UButton>
        </Can>
      </div>
    </template>
</template>

@lanwu114 https://nuxt.com/docs/4.x/api/composables/use-state Check the docs or send your code example

hi Psycarlo.My code is very simple. Every time I enter this route page, the console prints "createProduct" twice. Even if I move my defineAbilityto the shared folder, the same issue persists. I don't know how to use useState to resolve this situation... As a beginner, perhaps I'm a bit slow, and I'm really sorry for that.

By the way, your avatar is very handsome.

Image

lanwu114 avatar Sep 10 '25 02:09 lanwu114

@lanwu114

Wrap the defineAbility around 'useState' composable from nuxt

Psycarlo avatar Sep 10 '25 05:09 Psycarlo

@lanwu114

Wrap the defineAbility around 'useState' composable from nuxt My code was originally like this:

const createProduct = defineAbility(() => {
  console.log('createProduct')
  return true
})

Now I've changed it to this:

const createProduct = useState('createProductAbility', () => {
  return defineAbility(() => {
    console.log('createProduct')
    return true 
  })
})

However, my console still prints "createProduct" twice. This is giving me a headache.

lanwu114 avatar Sep 10 '25 08:09 lanwu114

useState

hi Barbapapazes.I encountered the issue of requests being sent twice today while testing nuxt-authorization, but I'm not sure how to resolve it based on your answer. Could you please provide a clear and easy-to-understand solution for reference? I believe I'm certainly not the only one who doesn't know how to handle this tricky problem. thinks

In your code shared, I don't see any request. Could you please share a more realistic reproduction of your issue?

Barbapapazes avatar Sep 10 '25 08:09 Barbapapazes

useState

hi Barbapapazes.I encountered the issue of requests being sent twice today while testing nuxt-authorization, but I'm not sure how to resolve it based on your answer. Could you please provide a clear and easy-to-understand solution for reference? I believe I'm certainly not the only one who doesn't know how to handle this tricky problem. thinks

In your code shared, I don't see any request. Could you please share a more realistic reproduction of your issue?

https://github.com/lanwu114/leonwillow-nuxt Here is my simple code. For convenience, I didn't write any logical judgments inside. However, as you can see, after I start the project and every time I access http://127.0.0.1:3000, the console prints "this is createProduct" twice, which means createProductwas accessed twice. This phenomenon has caused me some confusion, and I'm not sure what to do about it.

Image

lanwu114 avatar Sep 10 '25 09:09 lanwu114

We just told you what to do.

Psycarlo avatar Sep 10 '25 10:09 Psycarlo

@lanwu114 this is an intended behavior.

On client, the defineAbility runs twice to avoid flash. On the server, the watchEffect is not running so running it within the ref is needed to correctly render the template. Then, on client, the watchEffect is needed to make sure the ability updates when a prop changes.

I know, this is far from optimal but I didn't find a better way. Feel free to suggest something if you have any idea?

https://github.com/Barbapapazes/nuxt-authorization/blob/263571786c9affb1c5d541599f8c18fdb4a8b494/src/runtime/components/Can.vue#L13-L18

Barbapapazes avatar Sep 12 '25 10:09 Barbapapazes

Maybe, something with a the callOnce could be useful to solve this.

Barbapapazes avatar Sep 12 '25 10:09 Barbapapazes

const can = useState<boolean>()

await callOnce(async () => {
  can.value = await resolve()
})

watchEffect(async () => {
  can.value = await resolve()
})

Barbapapazes avatar Sep 12 '25 10:09 Barbapapazes