0

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

Tiboo
  • 27
  • 4
  • 1
    https://stackoverflow.com/questions/7956563/remember-ajax-added-data-when-hitting-back-button – Carlos Alves Jorge Jan 28 '21 at 23:50
  • Thanks for the answer. I think sessionStorage could be the solution. But it makes me wonder how to implement it. For example I can save the result in the sessionStorage but how the other pages of my website will know that there is a new element saved and then start a special function ? var setsession = window.sessionStorage.setItem("result", "url"); var getsession = window.sessionStorage.getItem("result"); – Tiboo Jan 29 '21 at 09:51

0 Answers0