SetInterval has to be triggered whenever the time is getting changed? - javascript

Am using setInterval for updating the time, for that i have set 60000s as interval. whenever i load the page i will get the time and time is getting updated after 1 minute from when i have refreshed the page but not with respective to the time. Hence there is some delay in updating the time.
const UpdateTime= (props) => {
let date = new Date();
const [dateTime, setDateTime] = useState({
curTime: date.toLocaleDateString(),
timeStr: date.toLocaleTimeString().replace(/:\d{2}\s/, " "),
curDay: date.toLocaleDateString("en-US", { weekday: "short" })
});
useEffect(() => {
const interval = setInterval(() => {
let date = new Date();
setDateTime({
curTime: date.toLocaleDateString(),
timeStr: date.toLocaleTimeString().replace(/:\d{2}\s/, " "),
curDay: date.toLocaleDateString("en-US", { weekday: "short" })
});
},
60000
);
return () => { clearInterval(interval) }
}, [])
}
after loading the page, whenever the date.getSeconds() is reaching 00 from there i have to trigger the setinterval function.

Well, if you want to go in this way, I guess there's no other solution than this:
Because you can't 'trigger' intervals just simulating it (How to trigger a setInterval function on a user click?), you can use function which will be called by the interval. Then you can call that function when the date.getSeconds() reach 00. However for this you will need a second interval which triggered every second until it reach the 00 and than you can clear it. After you called it and the second is 00 you set the interval for 60 seconds.
It's necessary to reset the 60s interval or it will be inaccurate again.

i have used setTimeOut to call the interval function whenever date.getSeconds() becomes 0 for the first time. But the problem what i am facing is i couldn't able to clear the interval. I am getting more "inside timeout and inside interval" in the console its not clearing the previous log, i am expecting timeout to be one and whenever the setInterval runs then i have to get the "inside interval" in the console
const DateTime = (props) => {
let date = new Date();
let initialDiff = (date.getSeconds() == 0) ? 0 : (59 - date.getSeconds());
setTimeout(() => {
triggerDateUpdate()
console.log("inside timeout")
}, initialDiff * 1000);
const [dateTime, setDateTime] = useState({
curTime: date.toLocaleDateString(),
timeStr: date.toLocaleTimeString().replace(/:\d{2}\s/, " "),
curDay: date.toLocaleDateString("en-US", { weekday: "short" })
});
const interval = () => {
console.log("inside interval")
let date = new Date();
setDateTime({
curTime: date.toLocaleDateString(),
timeStr: date.toLocaleTimeString().replace(/:\d{2}\s/, " "),
curDay: date.toLocaleDateString("en-US", { weekday: "short" })
});
}
let triggerDateUpdate = () => {
interval();
setInterval(() => {
interval();
}, 60000)
}

Related

Show countdown when holding button then show alert

I'm trying to create a button, which on hold shows a countdown of 3 seconds, if kept on hold for 3 seconds it shows an alert, but for some reason the countdown doesn't reset properly AND the alert fires up anyway, at every click (after the timeout)
my code is:
const [showCountdown, setShowCountdown] = useState(false)
const [holdTimer, setHoldTimer] = useState(3)
var timer = 0, interval;
const refreshDown = () => {
setShowCountdown(true)
interval = setInterval(function(){
setHoldTimer((t) => t - 1)
},1000);
timer = setTimeout(function(){
if (confirm('Refresh page?')){
window.location.reload()
}
},3000)
}
const refreshUp = () => {
clearTimeout(timer)
clearInterval(interval)
setShowCountdown(false)
setHoldTimer(3)
}
my html button has these two:
<svg onMouseDown={() => refreshDown()} onMouseUp={() => refreshUp()}>
...
</svg>
Have you tried with useRef ?
const timer = useRef();
const interval = useRef();
const refreshDown = () => {
setShowCountdown(true);
interval.current = setInterval(function () {
setHoldTimer((t) => t - 1);
}, 1000);
timer.current = setTimeout(function () {
if (confirm("Refresh page?")) {
window.location.reload();
}
}, 3000);
};
const refreshUp = () => {
clearTimeout(timer.current);
clearInterval(interval.current);
setShowCountdown(false);
setHoldTimer(3);
};
React component is rerendered each time state or props are changed. When setHoldTimer is executed, it changes the state. It causes reexecuttion of component’s code, so local variables “timer” and “interval” are declared again with values “0” and “undefined”, also new “refreshUp” function is created referencing new “timer” and “interval”. When you release the mouse, new “refreshUp” is called, interval and timeout are not cleared.
Try to define timer and interval as a state or with “useRef”. This way they will not be redefined during rerender.

how to change time name every 5 minutes

I made a whatsapp bot using Baileys and made a werewolf game feature, I want the time to change every 5 minutes from morning to night then morning again like a loop until the winner is determined. I use setInterval but it causes spam
I also used Node Corn and the result is the same
the all_room json db
[
{
"code":"FJ32Q",
"group_id":"6288742689173-1610938001#g.us",
"time":"morning",
"night":0,
"status":"starting",
"vote":false
}
]
getTime (function to get time from db)
const getTime = (group) => {
let alldb = JSON.parse(fs.readFileSync('./database/ww/all_room.json'))
satu = alldb.find((obj => obj.group_id == `${group}`));
return satu.time
}
set_time (functon to change value)
const set_time = (times, group) => {
let alldb = JSON.parse(fs.readFileSync('./database/ww/all_room.json'))
satu = alldb.findIndex((obj => obj.group_id == `${group}`));
alldb[satu].time = times
fs.writeFileSync('./database/ww/all_room.json', JSON.stringify(alldb))
}
if(isWS(group.id)){ // true
setInterval(() => {
if(getTime() === "morning") {
set_time("night")
reply("the sun is setting be careful because the werewolves are starting to roam")
} else if(getTime() === "night") {
set_time("morning")
reply("the sun has risen")
}
}, 300000);
}
Result
this is even spam

rxjs countdown that triggers method

I am trying to make a 5 mins countdown that triggers a service method and reloads the 5 mins countdown (basically I am trying to reload some data every 5 mins)
constructor(
private reloadDataService: ReloadDataService,
private userService: UserService
) {
this.timer$ = timer(0, 1000).pipe(
scan(acc => --acc, 300),
takeWhile(x => x >= 0),
);
}
realod method is trigger by a button or every 5 mins
reload() {
this.lastRefresh = new Date();
this.reloadDataService.reload()
}
ngOnInit() {
this.getUserDetails();
}
I have tried with
this.timer$ = timer(0, 1000).pipe(
switchMap(() => this.reload()),
scan(acc => --acc, 300),
takeWhile(x => x >= 0),
);
but didn't work - how can I trigger the reload method every 5 mins?
One way is by using interval or timer function offered by rxjs.
Here is an example that I created.
countDown: Subscription = null;
minutes: number = 5;
counter: number = this.minutes * 60;
triggered: number = 0;
start timer function
startTimer(): void {
this.countDown ? this.stopTimer() : null;
this.countDown = interval(1000).subscribe(() => {
--this.counter;
if (!this.counter) {
this.trigger();
}
});
}
stop timer function
stopTimer(): void {
if (this.countDown) {
this.countDown.unsubscribe();
this.countDown = null;
}
}
trigger function that get executed when countdown finish
trigger(): void {
this.counter = this.minutes * 60;
this.stopTimer(); // unsubscribe timer
this.startTimer(); // re subscribe timer
this.triggered++;
// your code
}
codesandbox ui example
I hope this helps you, let me know if you build another solution.
Best wishes,
Dev.klodian
use the subscribe property of timer,
const source = timer(0, 300000);
source.subscribe((_) => this.reload());
Try below code. It will setup the the interval method and when subscribing to refreshInterval$ you can call reload method or any operation that you want to repeat.
const refreshInterval$: Observable<any> = timer(0, 300000)
.pipe(
// Boolean to kill the request if the user closes the component
takeWhile(() => this.killTrigger));
refreshInterval$.subscribe(() => {
// Your code here
});

Timer: Play very few Minutes a warnsignal for a duration

I want to build a "timer". User can define a duration and the interval. So it will start with a warnsignat, then there will be a warnsignal, which peeps every interval and at the end there should be one.
The problem is: it doesn't work.
The audio just plays all the time.
Possible errorsources:
peep.loop = false does not work
it does not block.
const peepUrl = require('./../../../Assets/peep.mp3');
const peep = new Audio(peepUrl);
peep.loop = false;
_peep = () => {
peep.play();
if(this.state.myInterval > 0) {
setTimeout(() => {
peep.play();
}, 60000*this.state.myInterval);
}
clearInterval(this.state.myDuration)
peep.play();
}

Make countdown in background task on ios react-native

Right now I have this in my componentDidMount() methode:
setInterval(() => this.getTimeUntil(getTheTimeToAdd, count++), 1000);
It calls another methode for updating every second to count down. I have a problem when the user is counting down the application might close or the iPhone goes to sleep.
I have tried to use both:
react-native-mauron85-background-geolocation
and:
react-native-background-timer
To keep the count down running even when the iPhone sleeps og the application is closed. Any suggestions?
What you can do is create new Dates for each invocation to see the elapsed time. Like
setInterval(function() {
Date d = new Date();
if (this.oldDate && this.oldDate.getTime() + DELAY_THRESHHOLD < d.getTime()) {
...
this.oldDate = d;
}
else {
... //should anything be here?
}
},500);
Since you're already using react-native-background-timer,
you can use the setInterval from the BackgroundTimer instance.
Assuming that you've linked the project correctly, you should be able to do
// In the constructor or the state
this.state = {
initialCounter: 120000, //Equivalents to 2 minutes
active: false, // To show or hide a label
}
componentWillMount() {
this.setIntervalId = BackgroundTimer.setInterval(() => {
if (this.state.initialCounter === 0) {
this.setState({
initialCounter: this.state.initialCounter,
active: true,
})
} else {
this.setState({
initialCounter: this.state.initialCounter - 1000,
active: false,
})
}
}, 1000)
}
// Make sure to unmount the listener when component unmounts
componentWillUnmount() {
BackgroundTimer.clearInterval(this.setIntervalId)
}
// Helper func to reinitiate the counter
_onUpdate = () => {
this.setState({ initialCounter: 120000, active: false })
}
// And inside your render you may display the timer by formatting with moment()
The docs are a bit misleading, since setInterval and clearInterval works on IOS too. Tested on package 2.0.1
Try this code, it should catch up every time the app wakes up.
const duration = 15; // duration in minute
const alertAt = Date.now() + duration * 60 * 1000;
const interval = setInterval(() => {
const remaining = alertAt - Date.now();
if (remaining < 0) {
// time is up
clearInterval(interval);
return;
}
console.log(remaining);
}, 10)

Categories

Resources