0

I am writing a VSCode extension using vscode.window.showOpenDialog. It shows a dialog for choosing a directory (Windows). The code works except for the async/await. It's not waiting for the dialog to close. How can I make function getDirectory wait for function showDialog to resolve the chosen directory?

Function getDirectory outputs log #1 immediately without waiting for function showDialog. At this point dir is empty. As expected, function showDialog() logs #2 after the dialog is closed.


extension.ts:

async function getDirectory(): Promise<void> {
    const dir = await showDialog();
    console.log("#1: " + String(dir)); //Outputs before dialog is closed.
}

function showDialog() {
    let dir = "";
    const options: vscode.OpenDialogOptions = {
        canSelectMany: false,
        openLabel: 'Select',
        canSelectFiles: false,
        canSelectFolders: true
    };
    vscode.window.showOpenDialog(options).then(fileUri => {
        if (fileUri && fileUri[0]) {
            console.log('#2: ' + fileUri[0].fsPath); //Outputs when dialog is closed.
            dir = String(fileUri[0].fsPath);
        }
    });
    return Promise.resolve(dir);
}

Console:

#1:
#2: c:\Path\To\Chosen\Directory
  • Typescript 4.3.2.
JΛYDΞV
  • 8,532
  • 3
  • 51
  • 77
oivron
  • 75
  • 4
  • 1
    You're not waiting for `.showOpenDialog()` but instead you immediately return a resolved `Promise` with an empty string. You already have `async`/`await` in the title and your script. So you should already know how to "wait" for `.showOpenDialog()` + [How to return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321) – Andreas Jun 29 '21 at 07:17
  • 1
    `return vscode.window.showOpenDialog(options).then( /* ... /*)` and inside the `.then` replace `dir = String(fileUri[0].fsPath);` with `return String(fileUri[0].fsPath);` – VLAZ Jun 29 '21 at 07:19
  • Thank you, [VLAZ](https://stackoverflow.com/users/3689450/vlaz). It finally works! BTW, the suggested answer does not solve the problem. – oivron Jun 29 '21 at 07:57
  • @oivron The answer is an explanation on how to use Promises – rioV8 Jun 29 '21 at 08:04
  • As a matter of fact, the suggested answer DOES work. Sorry, my mistake. And thank you @Shuhaib zahir! – oivron Jun 29 '21 at 08:11

1 Answers1

-1
function getDirectory(){
return new Promise(async (resolve,reject)=>{
  const dir = await showDialog();
  console.log("#1: " + String(dir)); //Outputs before dialog is closed.
})
   
}

function showDialog() {
    let dir = "";
    const options: vscode.OpenDialogOptions = {
        canSelectMany: false,
        openLabel: 'Select',
        canSelectFiles: false,
        canSelectFolders: true
    };
    vscode.window.showOpenDialog(options).then(fileUri => {
        if (fileUri && fileUri[0]) {
            console.log('#2: ' + fileUri[0].fsPath); //Outputs when dialog is closed.
            dir = String(fileUri[0].fsPath);
        }
    });
    return Promise.resolve(dir);
}
  • 1
    this does not solve the problem, it only adds needless complexity – rioV8 Jun 29 '21 at 07:31
  • Code only answers are not suitable. You should explain why and how this works for you. – XouDo Jun 29 '21 at 07:33
  • [Is it an anti-pattern to use async/await inside of a new Promise() constructor?](https://stackoverflow.com/q/43036229) – VLAZ Jun 29 '21 at 09:06