skip to Main Content

So I’m new to electron, still getting a hang of the IPC communication. I’m able to send and receive messages totally fine over IPC (meaning I can confirm in both directions the send and receive statements are firing). When I send a value from renderer to main, the value comes across totally fine and can be printed out normally. What I don’t understand is why when I try to send a value from main to renderer, no matter what the value will always come through as ‘undefined’. The send and receive statements are still firing, it’s just the value that will not come across properly.

Here I send from renderer to main:

const dataSend = "Test Data"
ipcRenderer.send('tester:send', {
    dataSend
});

Here in main I receive that signal, print out (successfully) the data that was sent with it, and then send a new value over a new signal back to the renderer:

ipcMain.on('tester:send', (e, options) => {
    console.log(options.dataSend);

    const newData = "The Final Data";
    mainWindow.webContents.send('tester:toRender', {
        newData
    });
});

Which is recieved in the renderer here:

ipcRenderer.on('tester:toRender', (e, options) => {
    console.log("YUP IT ARRIVED");
    console.log(options.newData);
})

The console.log still fires properly, but no matter what the data type or value, it will always come across as undefined. I’m so stuck I don’t understand, any help would be awesome.

I simply want a way to send a message from renderer to main to access some data, package that data up in main and send it back to renderer to use for visible html elements. I can’t figure out why I can send the message from main to renderer just fine and the receive code will execute, but the data is lost along the way.

EDIT: Here is my preload.js:

//NOTES:
// The preload function is mainly used for exposing nodes to the renderer
// to be used outside the scope of this file

const fs = require('fs');
const os = require('os');
const path = require('path');
const Toastify = require('toastify-js');
const { contextBridge, ipcRenderer} = require('electron');

//Allows use of functions from nods to be used inside main and render
contextBridge.exposeInMainWorld('os', {
    homedir: () => os.homedir()
});

contextBridge.exposeInMainWorld('path', {
    join: (...args) => path.join(...args)
});

contextBridge.exposeInMainWorld('Toastify', {
    toast: (options) => Toastify(options).showToast(),
});

contextBridge.exposeInMainWorld('ipcRenderer', {
    send: (channel, data) => ipcRenderer.send(channel, data),
    on: (channel, func) => ipcRenderer.on(channel, (event, ...args) => func(...args)),
});

2

Answers


  1. Try adding window.ipcRenderer = require('electron').ipcRenderer to your preload file.

    How is the ipcRenderer defined in your renderer?

    Login or Signup to reply.
  2. I think the problem is with how you redefine ipcRenderer.on, you pass in ...args in place of event when you run the func callback. Take a look at this updated code:

    contextBridge.exposeInMainWorld('ipcRenderer', {
        send: (channel, data) => ipcRenderer.send(channel, data),
    // before you just had func(...args) but the callback is actually (event, ...args)
        on: (channel, func) => ipcRenderer.on(channel, (event, ...args) => func(event, ...args)), 
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search