Reputation: 8677
Scenario:
This is my code:
const body = ref<{ identifier: string, password: string }>({
identifier: '',
password: ''
});
const {data, execute, error, pending} = await useFetch(`${config.public.baseUrl}/api/auth/local`, {
body,
lazy: true,
method: 'post',
immediate: false,
watch: [],
})
async function login() {
console.log("login");
await execute();
}
and template
<form @submit.prevent="login">
<label for="email">
Email
<input type="text" v-model="body.identifier">
</label>
<label for="password">
Password
<input type="password" v-model="body.password">
</label>
<button>Login</button>
</form>
unfortunately even if I do not click button this form will send post
request to /api/auth/local
every time when user type letter in this form.
This behavior is described in documentation:
https://nuxt.com/docs/api/composables/use-fetch
All fetch options can be given a computed or ref value. These will be watched and new requests made automatically with any new values if they are updated.
I need to override this feature.
Change of
v-model
to
v-model.lazy
helps a little bit, but I still can't control exact time when this request is send.
My current workaround
const body = ref<{ identifier: string, password: string }>({
identifier: '[email protected]',
password: ''
});
const loginBody = ref<{ identifier: string, password: string }>({
identifier: '',
password: ''
});
const {data, execute, error, pending} = await useFetch(`${config.public.baseUrl}/api/auth/local`, {
body: loginBody,
lazy: true,
method: 'post',
immediate: false,
watch: [],
})
async function login() {
console.log("login");
loginBody.value = body.value;
await execute();
}
is not enough good, because it sends actually 2 requests in the same time, but first is immediately cancelled.
Upvotes: 2
Views: 4528
Reputation: 8922
Your body is a ref()
and therefor your useFetch()
will watch it and execute again when it changes. You have two options:
ref()
for your body. Does it really need to be a ref? Is it used in <template>
? If you dont need a variable in your template, or if you use it in your template but it never changes then it does not need to be a ref()
useFetch()
set watch: false
so it will not execute when your body ref()
changesUpvotes: 0
Reputation: 71
I meet the same situation. You could just unref the option value for useFetch() by using {...loginbody}
.
const { data } = await useFetch('/login', { method: 'post', body: {...loginbody} })
Upvotes: 7
Reputation: 8677
Finally i achieved my goal writing function
async function login() {
if(JSON.stringify(loginBody.value) === JSON.stringify(body.value)) {
await execute();
} else {
loginBody.value = body.value;
}
}
Request is executed once always when login
function is called. It body changed his value, then assign to loginBody
triggers request. In other case we executing is manually by execute
.
Little over-engineered but works.
Upvotes: 0