I have a React component that is part of a React/Apollo Booking app. I store all the bookings in a SQL database that is hooked up with React-Apollo in between. Before the customer starts the payment process the database is sent temporary bookings to "hold" certain times and restrain other customers from booking the same time. And if a customer refreshes/leave the page I wanna remove those temp bookings from the Apollo DB.
The work flow goes like:
So the issue I have is that if a customer leaves on step 2, then I want to remove those booking from the DB. Can this be done like with the code below or do I need put like a timer on these temp bookings and remove after certain time from the DB if certain criteria is not met?
I have read several topics on the subject and tryed suggested solutions. I am guessing the call to the DB is asynchorone or the fact that props are involved are the issue and that is why it's not working.
componentDidMount() {
window.addEventListener('beforeunload', function () {
this.props.tempBookings.forEach(booking => {
removeBookingFromDB(booking.id)
})
}, false);
}
componentWillUnmount() {
window.addEventListener('beforeunload', function () {
this.props.tempBookings.forEach(booking => {
removeBookingFromDB(booking.id)
})
}, false)
}
The function you provide as a callback for the beforeunload
event is not bound to this
. Use an arrow function instead:
window.addEventListener('beforeunload', () => {
this.props.tempBookings.forEach(booking => {
removeBookingFromDB(booking.id)
})
}, false);
To correctly remove the listener on unmount you need to bind the handler to the component instance so that you can reference it in componentWillUnmount
:
class MyComponent extends React.Component {
// must be an arrow function
removeBookings = () => {
this.props.tempBookings.forEach(booking => {
removeBookingFromDB(booking.id)
})
}
componentDidMount() {
window.addEventListener('beforeunload', this.removeBookings, false);
}
componentWillUnmount() {
window.removeEventListener('beforeunload', this.removeBookings, false)
}
}