For context, I have a table showing incoming calls and the wait time for each call. The data array looks like this:
[ { 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 setTimeout to each object, but I'm completely lost.
So far I've found that it's possible to make a counter via an observer, but this of course 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 display the counter on each object? I was thinking 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>
Additionally, I want to return the waiting time in the format HH:mm:ss
.
P粉5961619152024-03-28 00:05:39
One solution is to wrap {{ showWaitingTime(call.created_at) }}
with <span>
, which is key
ed on timerCount
so that <span>
is re-rendered when timerCount
changes (thereby calling showWaitingTime
again to calculate the new Time string): p>
In the template, use <span>
to wrap the timestamp string with the key
bound to timerCount
:
waiting time: {{ showWaitingTime(call.created_at) }}
In the observer on calls
, use setInterval
to start the periodic timer. Always stop the timer using clearInterval
before starting a new timer and when uninstalling 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, }, }, }
Your watcher on timerCount
is effectively implementing setInterval
. Remove this code because the code in step 2 eliminates it.
export default { watch: { // timerCount: {⋯} // ⛔️ remove this watch } }
In showWaitingTime()
, calculate HH:mm:ss
:
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}` }, }, }
Demo p>