I am currently working on creating a timer using @pinia/nuxt within nuxt 3. I also have a requirement to send an http request to sync my database when the timer starts.
However, I'm encountering an issue where the http request is being triggered for each iteration of setInterval when I call the action start
, but I only want it to run once.
This particular code snippet pertains to the pinia module. The start
action is invoked from an onClick
event within a component.
state: () => ({
timer: {
id: null,
isRunning: false,
time: 5,
timer: 0,
state: null,
} as Timer,
}),
actions: {
start() {
this.timer.isRunning = true
this.syncTimer()
if (!this.timer.timer) {
this.timer.timer = setInterval(() => {
if (this.timer.time > 0) {
this.timer.time--
} else {
clearInterval(this.timer.timer)
this.reset()
}
}, 1000)
}
},
stop() {
this.timer.isRunning = false
clearInterval(this.timer.timer)
this.timer.timer = 0
},
reset() {
this.stop()
this.timer.time = 1500
},
syncTimer() {
backendAPI<Timer>('/api/timer', {
method: 'POST',
body: this.timer
}).then(({ error, data }) => {
if (!error.value) {
const id = data.value?.id ?? ""
this.timer.id = id
this.timer.state = "created"
}
})
}
}
Here is the custom fetch composable backendAPI.ts
:
import type { UseFetchOptions } from 'nuxt/app'
import { useUserStore } from '@/stores/user'
import { defu } from 'defu'
export function backendAPI<T>(url: string, options: UseFetchOptions<T> = {}) {
const config = useRuntimeConfig()
const { token } = useUserStore();
const appToken = useRuntimeConfig().public.appToken
const defaults: UseFetchOptions<T> = {
baseURL: config.public.baseURL ?? 'http://localhost:4000',
key: url,
params: {
token: appToken
},
headers: token
? { Authorization: `Bearer ${token}` }
: {},
}
const params = defu(options, defaults)
return useFetch(url, params)
}