0
votes

I would like to send a function from my main to renderer process

I have an function which I export from the db.services.js module

// db.services.js
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert')

var DatabaseService = (function () {
    "use strict";
    var instance; //prevent modification of "instance" variable
    function Singleton() {
        if (instance) {
            return instance;
        }
        instance = this;
    }

    Singleton.create = function (db_uri) {
        //Singleton initialization code
        this.db_uri = db_uri
        this.db = undefined
        this.a = 0 // debugging async behavior
    }

    //instance accessor
    Singleton.getInstance = function () {
        return instance || new Singleton();
    };

    Singleton.getDB = function () {
        return this.db.db('xFilterDB') // directly return the used DB
    }

    Singleton.establishConnection = function (callback) {
        ... 
    }

    return Singleton;
}());

// exporting a "singleton" object to use with all views
DatabaseService.getInstance();

module.exports = DatabaseService;

I 'import' the function into my main electron process app.js

// app.js

const {
    app,
    BrowserWindow,
    ipcMain
} = require('electron');

const isDev = require('electron-is-dev');
const DatabaseService = require('./services/db.services'); 
app.on('ready', function () {
    DatabaseService.getInstance();
    DatabaseService.create("mongodb://localhost:27017");

    mainWindow = new BrowserWindow({
        width: 1024,
        height: 768,
        webPreferences: {
            nodeIntegration: true
        }
    })
    let url = 'file://' + __dirname + '/views/main.html'
    mainWindow.loadURL(url)
    mainWindow.webContents.on('did-finish-load', () => {
        console.log(DatabaseService);

        // 
        // [Function: Singleton] {
        //   create: [Function],
        //   getInstance: [Function],
        //   getDB: [Function],
        //   establishConnection: [Function],
        //   db_uri: 'mongodb://localhost:27017',
        //   db: undefined,
        //   a: 0
        // }

        mainWindow.webContents.send('database-service', 
            DatabaseService);  // <-- I am sending the function here
    });
    windows.push(mainWindow)
}

In main.html I do

<script>
        require('./main.js')
</script>

And in main.js

//main.js

ipcRenderer.on('database-service', (event, args) => {
    // ----- mongo connection ESTABLISH REGION START----
    // implicit async
    console.log(args); // <-- args is null here 
    ...
}

Any idea what is going wrong here?

Also, apparently this webContents.send('database-service', DatabaseService) is deprecated. So a better solution will be doubly appreciated.

1
Please explain the downvote to the question. - Roy2511

1 Answers

0
votes

You cannot send Function via IPC channel, becasue it cannot be serialized.

From docs:

Send an asynchronous message to the renderer process via channel, along with arguments. Arguments will be serialized with the Structured Clone Algorithm, just like postMessage, so prototype chains will not be included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an exception.