/* Hello everyone, I am working for the first time with electron. I have used JavaScript before. Can someone please show me what I am doing wrong trying to get the button onclick event to call a simple function with a console.log operation in it. Any help would be appreciated because I am not sure where all the pieces go together.
Here's my code: */
// main.js
const { app, BrowserWindow, ipcMain } = require("electron");
let win = null;
const createWindow = () => {
win = new BrowserWindow({
width: 800,
height: 600,
resizable: false,
webPreferences: {
nodeIntegration: true
}
});
win.loadFile("index.html");
};
app.whenReady().then(createWindow);
ipcMain.on("callMyFunction", (event, data) => {
// Prints inside the label called funcCallTxt
funcCallTxt.innerHTML = "This event: " + event + " and This data: " + data;
// Writes to the console just to see what in the variables
console.log("This event: " + event + " and This data: " + data)
});
// renderer.js
const { contextBridge, ipcRenderer } = require("electron");
contextBridge.exposeInMainWorld("electron", {
send: (channel, payload) => ipcRenderer.send(channel, payload),
});
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script defer src="renderer.js"></script>
<title>Call a Function</title>
</head>
<body>
<h1>A Function Call</h1>
<label for="funcCallTxt"></label>
<button type="button" onclick="callMyFunction()">Call My Function</button>
</body>
</html>
I forgot to mention. There is absolutely no output from this code. Nothing happens, and nothing is printed to the console.
A few things to point out for guidance:
funcCallTxt.innerHTML
in main.js won't work. This will need to be done in renderer.contextBridge.exposeInMainWorld
is a method that you need to use in a preload file, not renderer. Methods you define in this preload file will then be available in renderer thru the global variable you define in preload. In your example, this is global variable is electron
.event.returnValue
method of ipcMain event.To put it all together, here is a basic example of how that would work, based on your example:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script defer src="renderer.js"></script>
<title>Call a Function</title>
</head>
<body>
<h1>A Function Call</h1>
<label for="funcCallTxt"></label>
<button type="button" onclick="callMyFunction()">Call My Function</button>
</body>
</html>
main.js
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')
let win
function createWindow() {
win = new BrowserWindow({
width: 800,
height: 600,
resizable: false,
webPreferences: {
nodeIntegration: true,
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
win.webContents.on('did-finish-load', () => {
win.show()
})
}
app.whenReady().then(createWindow)
// Listen for funcCallTxt call from preload.
// Then return a value and console.log when called.
ipcMain.on('funcCallTxt', (event, data) => {
// "data" is what you passed to electron.send function in renderer
// Value to be sent back to renderer thru preload:
event.returnValue = data + ' = 2'
// "event" here is the Electron.IpcMainEvent object
console.log('This event: ' + event + ' and This data: ' + data)
})
preload.js
const { contextBridge, ipcRenderer } = require('electron')
// Expose following to renderer under 'electron' global
contextBridge.exposeInMainWorld('electron', {
// Send funcCallTxt directive to main with the data parameter from renderer
send: (data) => ipcRenderer.sendSync('funcCallTxt', data)
})
renderer.js
function callMyFunction() {
// Send the string "1 + 1" to main thru send function defined in preload and
// assign the return value from main to the variable "fromMain"
const str = '1 + 1'
const fromMain = electron.send(str)
document.querySelector('[for="funcCallTxt"]').innerHTML = fromMain
}