Harmonic
Harmonic

Reputation: 377

Electron - IPC - sending data between windows

In the main process, I create a window called mainWindow. On a button click, I create a new browserWindow called notesWindow.

What I want to do is send data from notesWindow to mainWindow

What I did is used IPC send to first send the data from notesWindow to the main process, retrieve the data on the main process, then send that data to mainWindow, but mainWindow is unable to receive the sender event. Sending data to the main process works fine, but from the main process to browserWindow doesn't seem to work.

main.js

const ipcMain = require('electron').ipcMain;

ipcMain.on('notes', function(event, data) {
      console.log(data) // this properly shows the data
      event.sender.send('notes2', data);
});

noteWindow.js

const ipcRenderer = require('electron').ipcRenderer;
ipcRenderer.send('notes', "new note");

mainWindow.js

const ipcRenderer = require("electron").ipcRenderer;
ipcRenderer.on('notes2', function(event, data) {
    // this function never gets called
    console.log(data);
});

Can anyone explain what I'm doing wrong? Thanks in advance!

Upvotes: 11

Views: 19142

Answers (2)

CircleOnCircles
CircleOnCircles

Reputation: 4394

There is no need to setup ipc hub on main.js. Here is how I would do it.

The key here is that if you want to have a direct ipc talk between renderer their need to know each other getCurrentWebContents().id.

Step 1: Create a main window global object

main.js

function createWindow() {
    mainWindow = new BrowserWindow(...);

    global.mainWindow = mainWindow;

    ...
}

Step 2: Send data to main window (and receive)

noteWindow.js

const ipc = require("electron").ipcRenderer;
ipc.sendTo(
          getGlobal("mainWindow").webContents.id,
          "ChannelForMainWindow",
          data,
          web_component.id // for main window to send back
        );

mainWindow.js

ipc.on("ChannelForMainWindow", (e, data, web_component_id) => {
    // do something
});

(Optional) Step 3: Send data back (and receive as well)

noteWindow.js

let's add listener for main window reply (if any)

const ipc = require("electron").ipcRenderer;

ipc.on("ChannelForNoteWindow", e => {
    ...
});

ipc.sendTo(
          getGlobal("mainWindow").webContents.id,
          "ChannelForMainWindow",
          data,
          web_component.id // for main window to send back
        );

mainWindow.js

ipc.on("ChannelForMainWindow", (e, data, web_component_id) => {
    // do something

    //send data back
    ipc.sendTo(web_component_id, "ChannelForNoteWindow");
});

Upvotes: 2

Arnelle Balane
Arnelle Balane

Reputation: 5487

mainWindow is not able to receive the event because it is not getting sent to it. The events.sender.send() code in main.js will send the data back to whoever sent the notes event, which in this case is the noteWindow. So the notes2 event is getting sent back to noteWindow instead of mainWindow.

To send the notes2 event to mainWindow, check out webContents.send(). This allows the main process to send data via events to a specific window. After some modifications to main.js it would look similar to this:

ipcMain.on('notes', function(event, data) {
    mainWindow.webContents.send('notes2', data);
});

Upvotes: 8

Related Questions