bouncer execute twice
<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:
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 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 :)
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 Should we close this issue?
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 https://nuxt.com/docs/4.x/api/composables/use-state Check the docs or send your code example
<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.
@lanwu114
Wrap the defineAbility around 'useState' composable from nuxt
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.
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?
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.
We just told you what to do.
@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
Maybe, something with a the callOnce could be useful to solve this.
const can = useState<boolean>()
await callOnce(async () => {
can.value = await resolve()
})
watchEffect(async () => {
can.value = await resolve()
})