I'm just learning Electron, and I'm trying to open a file and display it in a new window. I click a button in the initial (root) window, which then opens an "open file" dialog, from which I can get a file path. I would like to then open that file, create a window, and pass the contents of the file to the new window. My issue is in getting the string with the file contents into the callback function for when the window is ready; i that even possible? My main.js code:
function createWindow (templateFile, initialData)
{ console.log("Creating window....")
newWindow = new BrowserWindow({width: 800,
height: 600,
webPreferences: {preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true}
})
newWindow.loadFile(templateFile)
newWindow.webContents.openDevTools()
//This is what doesn't work; I want to take the initialData argument to the createWindow function,
//and get it into the 'did-finish-load' callback function
newWindow.webContents.on('did-finish-load', (event, initialData) =>
{ windowsArray[newWindow.webContents.id] = newWindow
console.log(initialData)
newWindow.webContents.send("initialDataLoad", initialData)
})
newWindow.on('closed', function () {newWindow.object = null})
}
ipcMain.on("new-sheet", (event, gameDefinitionFile) =>
{ console.log("Loading " + gameDefinitionFile)
let gameDefContents
fs.readFile(gameDefinitionFile, 'ascii', (err, gameDefContents) => {})
createWindow("defaultSheet.html", gameDefContents)
})
I have read that you can just make a new attribute on the webContents object and then refer to it from the renderer process, but that does not sound like the actual right thing to do. So, what should I do instead?
full code at https://gitlab.com/sjbrown8/osiris
The webContents
way should solve your problem in an easy way. It's straightforward: you create and collect all data the window needs in advance, then you spawn the window with that.
There a a few constraints with the webContents
way, because the webContents
object that you create on main
is serialized and send to render
- meaning, both processes have independent versions of the object:
But with plain initialization data: it's easy and understandable.
Edit:
Sure, the send methods needs a channel name and an optional objekt, that is the data that you want to send. You can write a function like so:
sendPersonData(personData) => {
webContents.send('person-data-updated', personData);
);
Or if you want a function that takes a callback for flexible sending:
updatePersonData(personData, senderCallback) => {
updatedPersonData = functionToUpdatePersonData(personData);
senderCallback(personData);
}
// and use that like so:
updatePersonData({name: 'John Doe'}, sendPersonData);