To get in context, I have a table that shows incoming calls and the waiting time for every call. The data array looks like:
[
{
id: 1,
patient_name: lorem ipsum,
created_at: 2022-02-02 09:10:35,
...
},
{
id: 2,
patient_name: dolor ipsum,
created_at: 2022-02-02 09:00:35,
...
}
]
I'm trying to figure out how to assign a setTimeout for each object, but I'm completely lost.
So far, I found that a counter can be made through a watcher, but of course this only acts as a "global" counter.
watch: {
timerCount: {
handler (value) {
if (value > 0) {
setTimeout(() => {
this.timerCount++
}, 1000)
}
},
immediate: true // This ensures the watcher is triggered upon creation
}
},
Is there a way to use a function to show a counter on each object? I was thinking in something like this:
<template>
<span v-for="call in calls" :key="call.id">
Requested at: {{ call.created_at }}
waiting time: {{ showWaitingTime(call.created_at) }} // <- Not sure if this can be done
</span>
</template>
...
<script>
....
methods: {
showWaitingTime (created_at) {
// get diff in seconds between created_at and now
// do something here with a timeOut() to increment the object property...
}
}
</script>
In addition, I would like to return the waiting time in HH:mm:ss
format.
One solution is to wrap the {{ showWaitingTime(call.created_at) }}
with a <span>
that is key
ed on timerCount
, so that the <span>
is re-rendered when timerCount
changes (thus calling showWaitingTime
again to compute the new time string):
In the template, wrap the timestamp string with a <span>
that has its key
bound to timerCount
:
waiting time: <span :key="timerCount">{{ showWaitingTime(call.created_at) }}</span>
In a watcher on calls
, use setInterval
to start a periodic timer. Be sure to stop the timer with clearInterval
before starting a new timer and when unmounting the component.
export default {
beforeUnmount() {
clearInterval(this._updateTimer)
},
// Vue 2 equivalent of beforeUnmount()
beforeDestroy() {
clearInterval(this._updateTimer)
},
watch: {
calls: {
handler(calls) {
clearInterval(this._updateTimer)
if (calls.length) {
this._updateTimer = setInterval(() => this.timerCount++, 1000)
}
},
immediate: true,
},
},
}
The watcher you have on timerCount
is effectively implementing setInterval
. Remove that code since it's obviated by the code in step 2.
export default {
watch: {
// timerCount: {⋯} // ⛔️ remove this watch
}
}
In showWaitingTime()
, calculate the HH:mm:ss
from the difference between the given time and now:
export default {
methods: {
showWaitingTime(created_at) {
const diff = new Date() - new Date(created_at)
const twoD = x => `${Math.floor(x)}`.padStart(2, '0')
const HH = twoD((diff / (60 * 60 * 1000)) % 24)
const mm = twoD((diff / (60 * 1000)) % 60)
const ss = twoD((diff / 1000) % 60)
return `${HH}:${mm}:${ss}`
},
},
}