There is working code that opens a browse for file dialog in another question. I’d like to make this an await async call.
Here is the original question and it works in my tests.
I’ve added the snipper here for convenience:
// wait for window to load
window.addEventListener("load", windowLoad);
// open a dialog function
function openFileDialog (accept, multy = false, callback) {
var inputElement = document.createElement("input");
inputElement.type = "file";
inputElement.accept = accept; // Note Edge does not support this attribute
if (multy) {
inputElement.multiple = multy;
}
if (typeof callback === "function") {
inputElement.addEventListener("change", callback);
}
inputElement.dispatchEvent(new MouseEvent("click"));
}
// onload event
function windowLoad () {
// add user click event to userbutton
userButton.addEventListener("click", openDialogClick);
}
// userButton click event
function openDialogClick () {
// open file dialog for text files
openFileDialog(".txt,text/plain", true, fileDialogChanged);
}
// file dialog onchange event handler
function fileDialogChanged (event) {
[...this.files].forEach(file => {
var div = document.createElement("div");
div.className = "fileList common";
div.textContent = file.name;
userSelectedFiles.appendChild(div);
});
}
.common {
font-family: sans-serif;
padding: 2px;
margin : 2px;
border-radius: 4px;
}
.fileList {
background: #229;
color: white;
}
#userButton {
background: #999;
color: #000;
width: 8em;
text-align: center;
cursor: pointer;
}
#userButton:hover {
background : #4A4;
color : white;
}
<a id = "userButton" class = "common" title = "Click to open file selection dialog">Open file dialog</a>
<div id = "userSelectedFiles" class = "common"></div>
Here is what I have:
async browseForFile(acceptedTypes: string, multiple?: boolean): Promise<array> {
var element = document.createElement("input");
element.type = "file";
element.accept = acceptedTypes;
if (multiple) {
element.multiple = multiple;
}
new Promise((resolve, reject) => {
element.addEventListener("change", resolveCallback);
})
var resolveCallback = (event)=> {
return event.currentTarget.files;
}
element.dispatchEvent(new MouseEvent("click"));
}
Suggested usage:
try {
var files = await browseForFile("*.txt");
}
catch(error) {
// no files selected
}
The answer I posted below seems to work if the user selects a file. But if they click cancel the promise is not rejected.
2
Answers
This seems to be working. I haven't tested in all browsers.
You need to return the promise so you can await the function.
And the promise needs to call
resolve()
with the value that you want returned byawait
.