Passing Data to Windows in Electron

I'm learning Electron and working with multiple windows and IPC. In my main script I have the following:

var storeWindow = new BrowserWindow({
  width: 400,
  height: 400,
  show: false
});

ipc.on('show-store-edit', function(event, store) {
  console.log(store);
  storeWindow.loadURL('file://' + __dirname + '/app/store.html');
  storeWindow.show();
});

And in my primary window's script, I have the following inside of a click event handler, pulling in a list of stores:

$.getJSON("http://localhost:8080/stores/" + item.id).done(function(store) {
   ipc.send('show-store-edit', store);
});

On the console, I am printing the store data from my server. What I'm unclear on is how to get that data into the view for my storeWindow:store.html. I'm not even sure I'm handling the sequence of events correctly but they would be:

  • click Edit Store
  • get store data from server
  • open new window to display store data

or

  • click Edit Store
  • open new window to display store data
  • get store data from server

In the latter, I'm not sure how I would get the ID required to fetch the store from the storeWindow's script.


To send events to particular window you can use webContents.send(EVENT_NAME, ARGS) (see docs). webContents is a property of a window instance:

// main process
storeWindow.webContents.send('store-data', store);

To listen for this event being sent, you need a listener in a window process (renderer):

// renderer process
var ipcRenderer = require('electron').ipcRenderer;
ipcRenderer.on('store-data', function (event,store) {
    console.log(store);
});

You need the ipcMain module to achieve this... As stated in the API "When used in the main process, it handles asynchronous and synchronous messages sent from a renderer process (web page). Messages sent from a renderer will be emitted to this module."

API Docs for the ipcMain module: https://electronjs.org/docs/api/ipc-main

To use the ipcMain you need to have nodeIntegration enabled on webPreferences

win = new BrowserWindow({
    webPreferences: {
        nodeIntegration: true,
    }
})

Be careful this may cause security issues.

For example: Let's say we want to pass a configuration (json) file to the web page

(Triple dots (...) represent your code that is already placed inside the file, but is not relevant to this example)

main.js

...

const { readFileSync } = require('fs') // used to read files
const { ipcMain } = require('electron') // used to communicate asynchronously from the main process to renderer processes.
...

// function to read from a json file
function readConfig () {
  const data = readFileSync('./package.json', 'utf8')
  return data
}

...
// this is the event listener that will respond when we will request it in the web page
ipcMain.on('synchronous-message', (event, arg) => {
  console.log(arg)
  event.returnValue = readConfig()
})
...

index.html

...    
<script>
    <!-- import the module -->
    const { ipcRenderer } = require('electron')

    <!-- here we request our message and the event listener we added before, will respond and because it's JSON file we need to parse it -->
    var config = JSON.parse(ipcRenderer.sendSync('synchronous-message', ''))

    <!-- process our data however we want, in this example we print it on the browser console -->
    console.log(config)

     <!-- since we read our package.json file we can echo our electron app name -->
     console.log(config.name)
</script>

To see the console of the browser you need to open the dev tools, either from the default Electron menu or from your code. e.g. inside the createWindow() function

 win.webContents.openDevTools()