Search code examples
javascriptelectronelectron-forge

Electron showOpenDialog arrow function (event.send) not working


I'm following the dialog example for opening files from: https://github.com/electron/electron-api-demos

I copied the code from the example. The open file dialog does in fact work and I'm able to select a file but can't figure out why the arrow function to send the file path back to renderer doesn't work(nothing is logged with console.log).

Can anyone spot what's wrong? The project was started using electron-forge and my OS is linux. Thanks

index.js

const { app, BrowserWindow, ipcMain, dialog, } = require('electron');
require('electron-reload')(__dirname);
const path = require('path');

// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) { // eslint-disable-line global-require
  app.quit();
}


const createWindow = () => {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  });

  // and load the index.html of the app.
  mainWindow.loadFile(path.join(__dirname, 'index.html'));

  // Open the DevTools.
  mainWindow.webContents.openDevTools();
};

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and import them here.


ipcMain.on('open-file-dialog', (event) => {
  dialog.showOpenDialog(
    {
      properties: ['openFile',]
    },
    (files) => {
      console.log('ok')
      if (files) {
        event.sender.send('select-file', files)
      }
    })
})

index.html

<!DOCTYPE html>
<html>

<head>
  <title>Hello</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

</head>

<body>
  <div>
    <div>
      <button class="demo-button" id="select-directory">Select file</button>
      <span class="demo-response" id="selected-file"></span>
    </div>
    <br><br>
  </div>
  <script>
    const electron = require('electron')
    const { ipcRenderer } = electron

    const selectDirBtn = document.getElementById('select-directory')

    selectDirBtn.addEventListener('click', (event) => {
      ipcRenderer.send('open-file-dialog')
    })

    ipcRenderer.on('select-file', (event, path) => {
      console.log(path)
      document.getElementById('selected-file').innerHTML = `You selected: ${path}`
    })

  </script>
</body>

</html>

Solution

  • The dialog API has been modified with the release of Electron 6.

    dialog.showOpenDialog() and other dialog functions now return promises and no longer take callback functions. There also are synchronous counterparts which return the selection result in a blocking fashion, e.g. dialog.showOpenDialogSync().

    Example usage (in renderer process)

    const remote = require("electron").remote
    const dialog = remote.dialog
    
    dialog.showOpenDialog(remote.getCurrentWindow(), {
        properties: ["openFile", "multiSelections"]
    }).then(result => {
        if (result.canceled === false) {
            console.log("Selected file paths:")
            console.log(result.filePaths)
        }
    }).catch(err => {
        console.log(err)
    })
    

    As of February 2020, the electron-api-demos use Electron 5. That is why their dialog calling code still uses the old form.