javascript - electron app json data to renderer using ipc - TagMerge
2electron app json data to renderer using ipcelectron app json data to renderer using ipc

electron app json data to renderer using ipc

Asked 5 months ago
0
2 answers

The wiring of your IPC is a bit mixed up and confusing. To simplify your scripts, try separating them into their own functionality. IE: Use your preload.js script to allow communication between the main process and render process(es) only.

Not knowing what database you are using, I will assume your database code is correct and functional.

Below is an example of how I would set-up my preload.js script and use it to communicate between processes.


This preload.js script uses whitelisted channel names to identify which IPC lines of communication can be used, similar to Node.js eventName.

preload.js (main process)

// Import the necessary Electron components.
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': [],
        // From render to main and back again.
        'sendReceive': [
            'message' // Channel name
        ]
    }
};

// Exposed protected methods in the render process.
contextBridge.exposeInMainWorld(
    // Allowed 'ipcRenderer' methods.
    'ipcRender', {
        // From render to main.
        send: (channel, args) => {
            let validChannels = ipc.render.send;
            if (validChannels.includes(channel)) {
                ipcRenderer.send(channel, args);
            }
        },
        // From main to render.
        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));
            }
        },
        // From render to main and back again.
        invoke: (channel, args) => {
            let validChannels = ipc.render.sendReceive;
            if (validChannels.includes(channel)) {
                return ipcRenderer.invoke(channel, args);
            }
        }
    }
);

For brevity, I have included your database code within the below main.js file.

main.js (main process)

'use strict';

const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const electronIpcMain = require('electron').ipcMain;

const nodePath = require("path");

// db = require('db'); // Your (connected) database

let window;

function createWindow() {
    const window = new electronBrowserWindow({
        x: 0,
        y: 0,
        width: 800,
        height: 600,
        show: false,
        webPreferences: {
            nodeIntegration: false,
            contextIsolation: true,
            preload: nodePath.join(__dirname, 'preload.js')
        }
    });

    window.loadFile('index.html')
        .then(() => { window.show(); });

    return window;
}

electronApp.on('ready', () => {
    window = createWindow();
});

electronApp.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        electronApp.quit();
    }
});

electronApp.on('activate', () => {
    if (electronBrowserWindow.getAllWindows().length === 0) {
        createWindow();
    }
});

// ---

// From render to main and back again
electronIpcMain.handle('message', (event, obj) => {
    // Create the table
    db.createTable("medicine", (succ, msg) => {
        if (succ) {
            console.log(msg);
        } else {
            console.log('An error has occurred. ' + msg);
        }
    });

    console.warn(obj);

    // Insert your data object
    if ((db.valid("medicine"), location)) {
        db.insertTableContent("medicine", obj, (succ, msg) => {
            console.log('Success: ' + succ);
            console.log('Message: ' + msg);
        });
    }

    let rows;

    // Retrieve all rows
    db.getAll("medicine", (succ, data) => {
        // succ - boolean, tells if the call is successful
        // data - array of objects that represents the rows.
        // console.warn(data);
        rows = data;
    });

    console.warn(rows);

    return rows; // Simple return the result via IPC

    // Testing purposes.
    // let rows = [
    //     {"name": "Amoxicillin", "weight": "250mg"},
    //     {"name": "Codeine", "weight": "50mg"},
    //     {"name": "Penicillin", "weight": "25mg"}
    // ];
    //
    // rows.push(obj);
    //
    // console.log(rows);
    //
    // return rows;
})

Lastly, I have tried to implement what the basic functionality of your index.html file may be like.

index.html (render process)

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Medicine</title>
    </head>

    <body>
        <h1>Add Medicine</h1>
    
        <label for="name">Name: </label>
        <input id="name" type="text">

        <label for="weight">Weight: </label>
        <input id="weight" type="text">

        <input id="button" type="button" value="Add">
    </body>

    <script>
        let name = document.getElementById('name');
        let weight = document.getElementById('weight');

        document.getElementById('button').addEventListener('click', () => {
            // From render to main and (.then) back again
            window.ipcRender.invoke('message', {"name": name.value, "weight": weight.value})
                .then((rows) => {
                    console.log(rows);
                })
        })
    </script>
</html>

Source: link

0

The ipcRenderer module allow communication from a renderer process to the main process. The basic structure for sending a message asynchronously to main process is:
ipcRenderer.send (channel, [, arg1][, arg2], [,...})
Example:
//renderer.js
const ipc = require('electron').ipcRenderer;
ipc.send('hello','a string', 10);
To receive a reply of asynchronous message from the main process, Electron uses the following structure:
ipcRenderer.on(channel, listener)
Example:
//renderer.js
ipc.on('fromMain', (event, messages) => {
 // do something
}
The ipcRenderer.once(channel, listener) works similar to the above method with one exception. It is the one time listener function for the event and removed after invoking:
//renderer.js
ipc.once('fromMain', (event, messages) => {
 // do something
}

Source: link

Recent Questions on javascript

    Programming Languages