Search code examples
javascriptnode.jselectronipc

Cannot send the data from main process to render in Electron


I am beginner to Electron, and I am developing an educational game. When the user clicks the start button, I want the main process to fetch information from the storage folder (I am ok with data being open to users). The main process accomplishes that without a problem.

main.js

ipcMain.on('load-sets', (event) => {
  const directoriesInDIrectory = fs.readdirSync(folderName, { withFileTypes: true })
    .filter((item) => item.isDirectory())
    .map((item) => item.name);
    event.sender.send("loaded-sets", directoriesInDIrectory);
})

Then, I use ipcRenderer in preload.js to receive the message.

preload.js

ipcRenderer.on("loaded-sets", (event, package) => {
    window.loaded_sets = [];
    for (var i = 0; i < package.length; i++) {

        window.loaded_sets[i] = package[i];
    }
})

Finally, I expose the sets via contextBridge:

contextBridge.exposeInMainWorld("api", {
    LoadFiles,
    quit,
    sets: () => window.loaded_sets,
    sentToRender,
})

However, when I run the following code in render.js: console.log(window.api.sets())

it outputs undefined.

I've already tried using postMessage and eventListeners associated with it. Also, I've tried to get the variable via another function:


function sentToRender() {
    return window.loaded_sets;

The function was also exposed and could be called in the renderer process. Yet, the output was still undefined.


For those wondering why I won't send the data straight to the renderer, the renderer returns error when I try require ipcRenderer and I heard that it is a good practice to navigate data through preload. Is there a solution?


Solution

  • In main.js

        ipcMain.on('load-sets', (event) => {
          const directoriesInDIrectory = fs.readdirSync(folderName, { 
        withFileTypes: true })
        `enter code here`.filter((item) => item.isDirectory())
        .map((item) => item.name);
      event.sender.send("loaded-sets", directoriesInDIrectory);
    })
    

    In preload.js

    contextBridge.exposeInMainWorld("api", (package)=> ipcRenderer.on("loaded-sets", (package)))
    

    In renderer.js

    window.api((event, package) => {
            window.loaded_sets = [];
            for (var i = 0; i < package.length; i++) {
        
                window.loaded_sets[i] = package[i];
               
            }
            console.log(window.loaded_sets)
           
        })