This is my code:
<script>
function sendFieldData() {
var email = document.getElementById('EmailComprador').value;
var telefone = document.getElementById('TelefoneComprador2').value;
var nome = document.getElementById('NomeComprador2').value;
var data = {
CustomerEmail: email,
CustomerName: nome,
CustomerPhone: telefone,
};
if (email) {
let curfetchUrl = `${window.location.pathname}?handler=SaveAbandonedCart`;
fetch(curfetchUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value
},
body: JSON.stringify(data)
})
.then(response => {
if (!response.ok) {
return response.text().then(text => { throw new Error(text); });
}
return response.json();
})
.then(responseData => {
console.log('salvo com sucesso', responseData);
})
.catch(error => {
console.error('erro:', error);
});
}
}
window.addEventListener('beforeunload', function (event) {
setTimeout(sendFieldData, 0);
});
</script>
At first it only calls the method on the IndexModel when I reload the page, but that's not what I want. I want when the user clicks on close tab to trigger the event to the backend as well.
Obs.: I already used unload, it didn't work. I'm using Razor, Js and C#
The issue is that the beforeunload
event listener is not reliable. Sending analytics when the page closes has become so commonplace that an API was added to handle it: Beacon API
Here's your JavaScript with that adjustment. Note that I moved some logic around a bit so we can build the data
object before sending the beacon.
function getData() {
var email = document.getElementById("EmailComprador").value;
var telefone = document.getElementById("TelefoneComprador2").value;
var nome = document.getElementById("NomeComprador2").value;
return {
CustomerEmail: email,
CustomerName: nome,
CustomerPhone: telefone,
};
}
document.addEventListener("visibilitychange", function logData() {
if (document.visibilityState === "hidden") {
const curfetchUrl = `${window.location.pathname}?handler=SaveAbandonedCart`;
const data = getData();
if (data.CustomerEmail) {
const requestSucceeded = navigator.sendBeacon(
curfetchUrl,
JSON.stringify(data)
);
if (requestSucceeded) {
console.log("salvo com sucesso");
} else {
console.error("erro");
}
}
}
});
If there are issues with using this API, like if you need to customize request properties or need to handle the response from the server, then this won't be a good fit. Instead try your original code but add "keepalive: true" to the fetch
call. You'll also need to switch to using visibilitychange
instead of beforeunload
like in the first example.
//...
fetch(curfetchUrl, {
method: "POST",
keepalive: true, // here's the adjustment
headers: {
"Content-Type": "application/json",
RequestVerificationToken: document.querySelector(
'input[name="__RequestVerificationToken"]'
).value,
},
body: JSON.stringify(data),
})
//...