'Blocking execution until user selects an option from the browser's download modal
I'm using window.location.href = some_url in a javascript bit. This brings up a menu from the browser, like so:
This is already happening within a promise - I have other .then() after, but I'd like them to hold on until the user has selected something from that menu.
Any way to access this? Code bits:
$.ajax({
url: url,
type: "POST",
data: formData,
contentType: false,
processData: false
})
.done(function(response, jqXHR){
new Promise(function(resolve, reject){
if (response.download){
console.log("downloading files sent.... ")
window.location.href=response.download.url
// I'd like to block here on the popup window before moving
resolve(response);
} else {
console.log("No downloads.")
resolve(response);
}
return response
})
.then(...)
Solution 1:[1]
Okay, so the real answer is you need to not be lazy and use something like a blob instead. Client-side, something like that:
$.ajax({
url: url,
type: "POST",
data: formData,
contentType: false,
processData: false
})
.done(function(response, jqXHR){
console.log("POST success,")
if (response.download.url) {
console.log("content to download")
fetch(response.download.url)
.then(function (resp){
let blob = resp.blob()
const header = resp.headers.get('Content-Disposition');
let filename = header.split(';')[1].split('=')[1];
response["filename"] = filename
return blob
// return resp
})
.then( function(blob) {
// blob = resp.blob()
const blob_url = window.URL.createObjectURL(blob)
const a = document.createElement('a')
a.style.display = "none"
a.href = blob_url
a.download = response.filename;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(blob_url)
// alert("download should be finished now")
return response
})
.then(function (response){
if (response.current_page && response.current_page.refresh) {
console.log("Refreshing page...")
location.reload(true);
console.log("Done.")
} else {
console.log("No refresh.")
}
return response
})
.catch((err)=>{console.log(err)} )
Then server-side - I'm using django, but the details would be similar in other frameworks:
logger.info(f"Creating tmp file for pdf response")
with tempfile.NamedTemporaryFile() as file:
file.write(pdf)
file.seek(0)
stream = file.read()
# build the http response
httpresponse = HttpResponse(content_type='application/pdf;', content=stream)
httpresponse['Content-Disposition'] = f'attachment; filename={value["filename"]}'
httpresponse['Content-Transfer-Encoding'] = 'binary'
return httpresponse
This works, because then I'm waiting on the fetch() call to finish before I move on to build the blob() & recover it locally. In other words, the "waiting" is managed by the fetch()' promise, and it only moves on once the server returned the file.
Then I can refresh the page without worrying, since I have the data in the browser's cache at that point. Loosing the state with a reload() at that point is fine.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | logicOnAbstractions |

