Reputation: 23
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
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
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
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