skip to Main Content

So, I’m trying to send data from my main.js, to be used in the renderer to draw divs to my html, after not being able to use the content from my JSON I decided to try and send a simple string, and the problem persists, a useless object.(Tried stringify, tried "toString()" and it only becomes an "Object".
Funnily enough, sending data from render to main works perfectly, I’m receiving it and storing it into a file that works just fine.

Main.js

const createMainWindow = () => {
      const win = new BrowserWindow({
      width: 600,
      height: 400,
      webPreferences: {
        nodeIntegration: true,
        preload: path.join(__dirname, "preload.js")
      }
    })
    win.loadFile('index.html')
    win.webContents.openDevTools();
    win.webContents.on('did-finish-load', () =>{
      win.webContents.send('loadJSON', "hello");
    })
  };

preload.js

contextBridge.exposeInMainWorld('electronAPI', {
    storeJSON: (data) => ipcRenderer.send('storeJSON', data),
    loadJSON: (data) => ipcRenderer.on('loadJSON', data)
})

vsticker.js (renderer)

window.electronAPI.loadJSON((data) =>{
    console.log(data);
});

I’m starting to get exhausted from reading electron’s docs to try and figure out why this is happening, I tried to wait until the page loads, tried this method of using a string instead of the contents fro my JSON, nothing seems to work, I just want to finish this.

Also, yes, I’ve read the post from the person that had a very similar problem, his solution was to wait until the page was fully loaded, I’ve tried this and it didn’t work.

2

Answers


  1. Here is the signature of ipcRenderer.on from the docs:

    ipcRenderer.on(channel, listener)

    As you can see, the first parameter of the listener function is event, and that’s what you are logging instead of the args. This should work better:

    window.electronAPI.loadJSON((_event, data) => {
      console.log(data);
    });
    
    Login or Signup to reply.
  2. ipcRenderer.on doesn’t send data, it sends a callback function. To pass data through it, the preload.js needs to have a function that takes the data as an argument and sends it forward to your handler on the renderer side. Your preload.js exposeInMainWorld should look more like this:

    contextBridge.exposeInMainWorld('electronAPI', {
        storeJSON: (data) => ipcRenderer.send('storeJSON', data),
        loadJSON: (callback) => ipcRenderer.on('loadJSON', (_event, data) => callback(data))
    });
    

    As you can see, the second argument isn’t your data itself, it’s an inline function that takes the data and passes it to a callback as a parameter.

    Check out Electron’s Inter-Process Communication docs for more details, specifically the "Pattern 3" section talking about main-to-renderer communication. It has examples and more specific information.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search