1

I'm building a system where a user is scored on the percentage of a video they have watched. If they leave/refresh / close the page I need to post their scoring data to an API endpoint.

  • I use the beforeunload event to fire the action when the user changes their location.

  • The action is handled using redux-saga.

  • I can see the action is being dispatched but it seems that the window closes before the call is made to the endpoint (chrome dev tools shows the call but with a status of canceled).

Is there any way to reliably ensure that the call is made to the endpoint? Surely there are a lot of sites (most notably e-learning ones) that handle this kind of behavior consistently, so there must be a solution.

Component:

componentDidMount() {
window.addEventListener('beforeunload', this.onUnload);

}

componentWillUnmount() {
window.removeEventListener('beforeunload', this.onUnload);

}

onUnload() { 
this.props.postScore(params);

}

Any help is greatly appreciated.

Abdul Karim
  • 4,359
  • 1
  • 40
  • 55
AFK
  • 66
  • 9
  • The problem is that browser doesn't allow to send async requests on page close. You need to make it synchronous and use both events (`beforeunload` and `unload`). Read [this](https://stackoverflow.com/questions/4945932/window-onbeforeunload-ajax-request-in-chrome) – pumbo Jul 14 '17 at 05:10
  • @AlexM thank you. I suspected as much. Any idea how to accomplish that in redux-saga though? – AFK Jul 14 '17 at 05:27

1 Answers1

1

If redux store is your app state, which is about to be go kaput, this is a rare time you have to bypass the store.

Just synchronously read the store and directly post to the api.

But even this is only saving the progress when the browser fires "unload".

If the page becomes unresponsive, or the browser simply crashes, the handler and api call will never execute.

A simple tactic would be to continually update progress every x seconds

Ashley Coolman
  • 11,095
  • 5
  • 59
  • 81