javascriptelectron

A Simple Electron App with a Button that calls a function reports to the console


/* 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.


Solution

  • A few things to point out for guidance:

    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
    }