1

I am trying to do server call to save data using redux saga in react js on browser close/tab close using JavaScript events, but it closes the browser before calling service.

onClose = () =>{
  return this.props.saveData()  // saveData will save data using redux saga.
}

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

componentWillMount() {
  window.addEventListener('beforeunload',this.onClose);
}

I expect to call service and save data before closing browser or tab but it closes browser before calling service to save data

Brian Tompsett - 汤莱恩
  • 5,195
  • 62
  • 50
  • 120
Priyanka
  • 13
  • 1
  • 6

2 Answers2

1

One solution would be to establish a websocket connection on page load.

Closing the tab/browser will close the connection, and your server will know immediately.

A well-established solution is socket.io, offering fallback to “long-polling” or regular polling if websockets aren’t available (you would need an “event based” approach to handling requests in that case).


According to jfriend00's answer to Websockets and scalability, they are pretty scalable:

A single server, configured appropriately can handle hundreds of thousands of simultaneous webSocket connections that are mostly idle since an idle webSocket uses pretty much no server CPU.

hugo
  • 1,660
  • 1
  • 10
  • 14
0

Browser close will not wait untill your service reach server and returns. Better you can change your implementation based on the below stackoverflow answer.

Trying to detect browser close event

Update:

Please try to return a boolean from your api and from that you can understood the hit reached to server. Then you can returning the close event to browser.

onClose = () =>{
   let status = this.props.saveData();  // saveData will save data using redux saga.
   if(status){
      return;
}

Updated:

onClose = () =>{
   let status = this.props.saveData();  // saveData will save data using redux saga.
   if(status){
      return;
}

componentDidMount() {
  setTimeout(function() {
     window.addEventListener('beforeunload',this.close);
  }, 2000);
}

componentWillMount() {
}
Alwin Jose
  • 230
  • 2
  • 8
  • Also browser close event is not predictable, sometimes it won't call as expected from my experience. – Alwin Jose Aug 10 '19 at 10:41
  • It is returning message.I dont want to return and display message.want to do call to server.not getting how to use code from the url you posted. – Priyanka Aug 10 '19 at 10:42
  • I tried with sample program and its work fine and its waiting for the response. once it reached return statement the tab closes instantly. – Alwin Jose Aug 10 '19 at 11:30
  • Thanks Alwin Jose. It works sometimes and sometimes it does not work. Also,it is not workingon IE11 – Priyanka Aug 10 '19 at 12:46
  • As i said earlier, browser close events not predictable. It may call or may not. May i know purpose of that api call while browser close. By that i will find any suitable solution. Any multiple login check are you doing? – Alwin Jose Aug 10 '19 at 12:57
  • I have one form in which user enters data.Then,by clicking save button values are saved in database.But if user does not press button manually and closes browser,then also values should be saved in database – Priyanka Aug 10 '19 at 12:58
  • The similar issue discussed very detailed here https://stackoverflow.com/questions/1375846/dealing-with-unsaved-form-data-when-user-closes-the-browser . "Closing a window is an act of cancellation. As the user never actively submitted the form, theres no guarantee that they want the data saved (it may not be correct), and you saving the data could cause problems for the user." – Alwin Jose Aug 10 '19 at 13:14
  • Is it possible that onClose I show one pop up box with ok and cancel button.And if user clicks on ok then data is saved in database – Priyanka Aug 10 '19 at 14:48
  • That's fine. However, the onbeforeunload is non-standard, so it's not supported by all browsers and sometime it won't work as expected. Thanks – Alwin Jose Aug 10 '19 at 17:49
  • From MDN : However, ensuring that the data has been sent during the unloading of a document is something that has traditionally been difficult for developers.This is a relatively newer API and doesn't seems to be supported by IE yet. https://stackoverflow.com/questions/4945932/window-onbeforeunload-ajax-request-in-chrome – Alwin Jose Aug 10 '19 at 17:51
  • beforeunload is not running in IE.Is it deprecated there – Priyanka Aug 12 '19 at 08:28
  • I believe the cause is that event binding isn't possible until the child window has finished loading. Please refer this https://stackoverflow.com/questions/8152361/javascript-beforeunload-event-not-working-in-ie and change your code accordingly. – Alwin Jose Aug 12 '19 at 08:49
  • onClose = () =>{ let status = setTimeout(this.props.saveData(),0); // saveData will save data using redux saga. if(status){ return; } Added setTimeout but still same not working in IE – Priyanka Aug 12 '19 at 10:28
  • I have updated the code with setTimeout. Please change it and try. – Alwin Jose Aug 13 '19 at 12:52
  • Please try it out. Please close the thread if its really solve your issue. – Alwin Jose Aug 15 '19 at 12:42
  • can you share your updated code snippet? so that i can gone through it easily. – Alwin Jose Aug 19 '19 at 14:02