I have an issue with a Django project. I have developped a button which is supposed to generate and download a csv file. The function to achieve that is very long and so I used celery task to avoid monopolizing the server for only one user downloading.
To do that I have an ajax function which call api and wait for the end of the generating file. It works fine if the user stay on the same page.
<a class="dropdown-item" onclick="exportToExcel('mission', 'man')">TEST</a>
function exportToExcel(expt, t){
var selectedTime = $("#weekSelect").children("option:selected").val();
var week = '';
var year = '';
if (selectedTime)
{
var week = selectedTime.toString().split("/")[0].substring(1);
var year = selectedTime.toString().split("/")[1];
}
var current_path = location.pathname;
var manager = current_path.split("/")[1];
var url = "";
if (week === ""){
url = `/api/export/${expt}-${manager}/${t}/`;
}
else
{
url = `/api/export/${expt}-${manager}/${t}/${week}-${year}/`;
}
console.log(url)
$.get(url).done(function ExportAsyncResults(data) {
// bind syncResults to itself to avoid clashing with the prior get request
context: this
// see the URL setup for where this url came from
const exportAsyncUrl = `/api/export_async_results/${data.task_id}/`
$.get(exportAsyncUrl)
.done(function(asyncData, status, xhr) {
context: this
// if the status doesn't respond with 202, that means that the task finished successfully
if (xhr.status !== 202) {
// stop making get requests to AsyncResults
clearTimeout(ExportAsyncResults);
// to download - create an anchor element and simulate a click
const a = document.createElement('a');
document.body.appendChild(a);
a.style='display: none';
a.href=asyncData.location;
a.download=asyncData.filename;
a.click();
a.remove()
$.get(`/api/del/${asyncData.filename}/`)
}
// async task still processing
else {
// Call the function pollAsyncResults again after
// waiting 1 second.
setTimeout(function() { ExportAsyncResults(data) }, 10000);
}
})
// see PollAsyncResultsView in View Setup. If the celery
// task fails, and returns a JSON blob with status_code
// 500, PollAsyncResultsView returns a 500 response,
// which would indicate that the task failed
.fail(function(xhr, status, error) {
// stop making get requests to AsyncResults
clearTimeout(ExportAsyncResults);
// add a message, modal, or something to show the user
// that there was an error the error in this case
// would be related to the asynchronous task's
// error message
})
})
.fail(function(xhr, status, error) {
// add a message, modal, or something to show the user
// that there was an error
// The error in this case would be related to the main
// function that makes a request to start the async task
})
}
However if the user leave the page for another, I lose the api response and the download never happen.
So my question is : how do I manage ajax get request if user change page in the middle of the process ?
I read this stackoverflow Change page in the middle of Ajax request and it appears I have to prevent user to leave the page ?
Thx