electronipcipcrendereripcmain

Electronjs ipcRenderer.on not working properly


I am trying to send data from the main process to the renderer and the ipcRenderer.on function is being executed but the data is undefined...

This is the code to send the data:

mainWindow.webContents.on("did-finish-load", () => {
        let name = "test";
        mainWindow.webContents.send("updateSave", name);
})

And this to receive it:

ipcRenderer.on("updateSave", (e, data) => {
    console.log("data: " + data);
})

The console.log is beeing fired but it just says: data: undefined

And this is the preload file:

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

Does anybody know what I did wrong? Thanks


Solution

  • In your preload.js, you're defining ipcRenderer.on() as follows:

    on: (channel, func) => {
        ipcRenderer.on(
            channel,
            (event, ...args) => {
                func(...args)
            }
        )
    }
    

    Thus, event will never get passed to func() and is thus swallowed. Now, there are two possible solutions (personally, I'd go with (1) because it's easiest to implement and will make for cleaner code on both parts. However, please see the remark below):

    (1) You want to keep the signature in your renderer
    I.e., you want to still write ipcRenderer.on("channel", (event, data) => {});. Then you will have to change your preload code. I suggest to simply pass func to ipcRenderer like so:

    on: (channel, func) => ipcRenderer.on (channel, func)
    

    Then, any func parameter must have the signature (event, ...data) => {}.

    (2) You want to keep the signature in your preload
    I.e., you want to keep the code of your preload contextBridge definition. Then, any instance of ipcRenderer.on() in your renderer code will need to change to fit the signature (...data) => {} since there's no event parameter passed to the function.


    As a side note, it is considered a best practice if you don't expose Electron API function (such as ipcRenderer.on(), ipcRenderer.send() etc) to the renderer when proxying using a preload script, but instead provide discrete functions for your renderer code to choose from, as shown in Electron's official IPC tutorial.