Search code examples
javascriptnode.jselectron

What is the best way to pass arguments subwindow in electronjs prject


How can pass argument customer_ID while opening new sub window in electron appication

i have tried with modal.loadFile(${__dirname}/pages/Company/login.html?id=1234) but getting error electron: Failed to load URL: file:///Users/excelgraphics/Documents/Regular%20Jobs/OT/Aux%20service/Aux%20Services/pages/newService.html%3Fid=1234 with error: ERR_FILE_NOT_FOUND

const popupLogin = (htmlFile, parentWindow, width, height) => {
    let modal = new BrowserWindow({
        width: 600,
        height: 500,
        modal: true,
        resizable: false,
        icon: path.join(__dirname + '/public/auxwall/logos/favicon.png'),
        parent: MainWindow,
        frame: false,
        webPreferences: {
            preload: path.join(__dirname, 'preload.js'),
            contextIsolation: false,
            nodeIntegration: true,

        }
    })

    modal.loadFile(`${__dirname}/pages/Company/login.html`)

    return modal;
}

and i try to do this How to send a variable from the mainWindow to a childWindow in Electron JS?

but modal window can't access message from main process

can anyone help me to solve this issue?


Solution

  • Remembering that your modal is just a window without a frame, data can be passed back and forth by using Inter-Process Communication.

    To begin securing you Electron app you should really read up on Context Isolation.

    To pass the id to the newly created window, use the {window}.webContents.send method.

    Immediately after loading the login.html page, send the id to the window.

    In your main thread script...

    const popupLogin = (htmlFile, parentWindow, width, height) => {
    
        // Get the customers id from whatever source necessary.
        let id = 99;
    
        // Create the window.
        let modal = new BrowserWindow({
            width: 600,
            height: 500,
            modal: true,
            resizable: false,
            icon: path.join(__dirname + 
     '/public/auxwall/logos/favicon.png'),
            parent: MainWindow,
            frame: false,
            show: false, // Hide possible flash and DOM update(s).
            webPreferences: {
                preload: path.join(__dirname, 'preload.js'),
                contextIsolation: true, // Set to true
                nodeIntegration: true,  // Node integration (removed in Electron v12)
            }
        })
    
        // Load the window.
        // Note: The loadFile() method returns a promise.
        modal.loadFile(`${__dirname}/pages/Company/login.html`)
            .then(() => { modal.webContents.send('login:id', id); })
            .then(() => { modal.show(); }) // Now show the modal
    
        return modal;
    }
    

    preload.js (main thread)

    const contextBridge = require('electron').contextBridge;
    const ipcRenderer = require('electron').ipcRenderer;
    
    // White-listed channels.
    const ipc = {
        'render': {
            // From render to main.
            'send': [],
            // From main to render.
            'receive': [
                'login:id'
            ],
            // From render to main and back again.
            'sendReceive': []
        }
    };
    
    contextBridge.exposeInMainWorld(
        // Allowed 'ipcRenderer' methods.
        'ipcRender', {
            send: (channel, args) => {
                let validChannels = ipc.render.send;
                if (validChannels.includes(channel)) {
                    ipcRenderer.send(channel, args);
                }
            },
            receive: (channel, listener) => {
                let validChannels = ipc.render.receive;
                if (validChannels.includes(channel)) {
                    // Deliberately strip event as it includes `sender`
                    ipcRenderer.on(channel, (event, ...args) => listener(...args));
                }
            },
            invoke: (channel, args) => {
                let validChannels = ipc.render.sendReceive;
                if (validChannels.includes(channel)) {
                    return ipcRenderer.invoke(channel, args);
                }
            }
        }
    );
    

    login.html (render thread)

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
            <link rel="stylesheet" type="text/css" href="style.css">
            <script type="module" src="login.js"></script>
        </head>
        <body>
            ....
        </body>
    </html>
    

    login.js (render thread)

    (function() => {
            window.ipcRender.receive('login:id', (event, id) => { customerId(id); });
    })();
    
    function customerId(id) {
       console.log(id);
    }