ArtInLines
ArtInLines

Reputation: 90

Electron ipcMain & ipcRenderer fail to communicate with each other

I'm writing a desktop app with electron js and I wanna both send data from my main process to my renderer process and the other way around. For that I'm using the ipcMain and ipcRenderer, yet weirdly enough, while being able to send data via my renderer with ipcRenderer.send(), I cannot receive any data from my main process with ipcRenderer.on(). It just doesn't work for some reason.

Afterwards I tried to find the bug by writing a test, following electron's documentation. The test however doesn't work at all, since neither process seems able to send something to the other process. This is the code that I wrote for my test:

main.js:

const { app, ipcMain, BrowserWindow } = require('electron');

const createWin = async () => {
    const win = new BrowserWindow({
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false,
        },
    });
    win.loadFile('./index.html');
    return new Promise((resolve, reject) => {
        win.once('ready-to-show', () => {
            resolve();
        });
    });
};

app.whenReady().then(async () => {
    const win = await createWin();
    console.log('Ready to show');

    ipcMain.on('asynchronous-message', (event, arg) => {
        console.log(arg); // prints "ping"
        event.reply('asynchronous-reply', 'pong');
    });

    ipcMain.on('synchronous-message', (event, arg) => {
        console.log(arg); // prints "ping"
        event.returnValue = 'pong';
    });
});

index.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Test, please work</title>
    </head>
    <body>
        <script src="./app.js"></script>
    </body>
</html>

app.js:

const { ipcRenderer } = require('electron');

console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); // prints "pong"

ipcRenderer.on('asynchronous-reply', (event, arg) => {
    console.log(arg); // prints "pong"
});
ipcRenderer.send('asynchronous-message', 'ping');

Here's what the Renderer logs:

{ error: "reply was never sent" }

Here's the link to the documentation where I have the code from: https://www.electronjs.org/docs/api/ipc-main#sending-messages

Upvotes: 2

Views: 3474

Answers (1)

pushkin
pushkin

Reputation: 10199

This is happening because you're hooking up your event handlers too late.

You're only adding ipcMain.on after the page has loaded and ready-to-show has fired. You should either set them up earlier, like before you create the window, or just remove the await in await createWin().

For reference, Electron throws the error here

Upvotes: 2

Related Questions