beta alpha
beta alpha

Reputation: 23

Electron beginner, how to read file from menu to html?

I create a simple electron project, create a Menu, for open file, everything is fine until I got data from file. I found there is no document or $ object, how can I passing data to DOM, like p textContext?

dialog.showOpenDialog({properties: ['openFile']}, (filePath) => {
        // read the file
        fs.readFile(filePath[0], (err, data) => {
            if (err) {
                // do something
            } else {
                // this not work
                document.getElementsByTagName("p")[0].textContent = data.toString();
            }
        })
    });
}

Upvotes: 1

Views: 1175

Answers (3)

Victor Mog
Victor Mog

Reputation: 60

main.js:

 Menu.setApplicationMenu(Menu.buildFromTemplate([
      {
        label: '&File',
        submenu: [
          {
            label: 'Open',
            accelerator: 'CmdOrCtrl+O',
            click() {
              showOpen()
            }
          },
          { type: 'separator' },
          {
            role: 'quit',
            accelerator: 'CmdOrCtrl+Q'
          }
        ]
      }])
    
      function showOpen() {
        dialog.showOpenDialog({
          properties: ['openFile']
        }).then(result => {
          console.log(result.canceled)  // Optional
          console.log(result.filePaths) // Optional
          
          // Read first file of list (or process an array of files)
          readFile(result.filePaths[0]) 
        }).catch(err => {
          console.log(err)
        })
      }
    
      function readFile(filepath) {
        fs.readFile(filepath, 'utf-8', (err, data) => {
          if(err){
            alert("An error ocurred reading the file :" + err.message)
            return
          }
          console.log(JSON.parse(data)) // For JSON file only
        })
      }

Instead of console.log(JSON.parse(data)), you process the file and then send it to the browser using, for example, IPC

Upvotes: 0

pergy
pergy

Reputation: 5521

You have no access to document in the main process (where I suppose you have this code). You have to communicate between your processes by using IPC, code execution on HTML or even globals. (You can find lot of articles about it online) See electron's architecture for details.

An example to deal with this scenario could be

main.js

const { app, BrowserWindow, Menu, dialog } = require('electron')
const fs = require('fs')
const path = require('path')

app.once('ready', () => {
  let win = new BrowserWindow()
  win.loadURL(path.join(__dirname, 'index.html'))
  win.setMenu(Menu.buildFromTemplate([
    {
      label: 'Open File',
      click (menuItem, browserWindow, event) {
        dialog.showOpenDialog({
          properties: ['openFile']
        }, (filePath) => {
          fs.readFile(filePath[0], (err, data) => {
            if (!err) {
              browserWindow.webContents.send('print-file', data.toString())
            }
        })
        })
      }
    }
  ]))
})

index.html

<html>
  <body>
    <script>
      const { ipcRenderer } = require('electron')
      ipcRenderer.on('print-file', (event, datastr) => {
        document.getElementsByTagName("p")[0].textContent = datastr
      })
    </script>
    <p></p>
  </body>
</html>

Upvotes: 1

Blizzardengle
Blizzardengle

Reputation: 1071

I do not have an environment where I can test this right now but I think your writing the showOpenDialog incorrectly. If you look at the manual page the first argument is an optional browser window object. It looks like your not using one so your code should be:

dialog.showOpenDialog(null, {properties: ['openFile']}, (filePath) => {
        // read the file
        fs.readFile(filePath[0], (err, data) => {
            if (err) {
                // do something
                console.log('ERROR: ' + data);
            } else {
                // this not work
                console.log('PASS: ' + data);
                document.getElementsByTagName("p")[0].textContent = data.toString();
            }
        })
    });
}

When an argument (parameter) is optional you still need to send something in. Since you don't want to use it I sent in null so the showOpenDialog function knows your not going to use it. I also added some console.log() so you can test your results before trying to use the data.

Upvotes: 0

Related Questions