What is the proper way to do that? My goal is to save in database the count of minutes of the video the user has watched until he closed the page and set the video’s minutes to where he left off, next time he opens the very same video. I’ve tried to do that with beforeunload
event but the page is closing before the function return. I’m using async/await but I don’t know how to make sure the event finish to run properly. I’ve tried something like this in my react component:
const ec = async (e) => await handleBeforeUnload(e);
window.addEventListener('beforeunload', ec);
return () => {
window.removeEventListener('beforeunload', ec);
}
but doesn’t gurante that the function finish before leaving the page. What is the proper way to do that?
edit: here’s the rest of the code:
const handleBeforeUnload = async (event) => {
await save_timestamp();
}
const save_timestamp = async () => {
const v:IResumeVideo = {
seconds: timeline.current,
video_id: video_id
}
const response = await fetch('/api/save_video', {
method: 'POST',
body: JSON.stringify(v)
});
const result = await response.json();
}
3
Answers
It seems that using beforeunload is not recommended at all for your using case of saving the user’s state, see: https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event:
EDIT: I’ve briefly tested in a fiddle what happens if you have a async function on the visibilitychange, and it seems to be reliably fired. The code snippet in question is:
You can create a dedicated hook with
sendBeacon
as Elvis mentioned in the comment, in this way you can use also for different cases in different components without duplicating same codeThere is a web API, the Beacon API, to do exactly that and guarantee the data is sent even after the user leaves the page:
https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API