remote.getGlobal() not getting the update variable from main process


#1

I am using the global to store the instance objects in the main js.
The renderer process will update the global variable via ipc called, and will retrieved the global variable again using remote.getGlobal().

To make it clear, it actually an downloader app. I am using mt-files-downloader for handle the download.

Here is what I do:
When adding a download url in the renderer, it will be passed to the main js via ipc call and then using the downloader module to start the download:

    global.ditems = {}// declare the global variable
    ipc.on('add-item', function(event, arg){
        let ctime = new Date().getTime()
        let dl = downloader.download(arg, '/tmp/'+ctime'+.mp3').start();
       global.ditems[ctime] = dl // set the global variable objects with current download object.
       console.log(global.ditems)//show the variable
       mainWindow.webContents.send('addnewitem',ctime );// send it to the renderer process.
    }) 

So in the mainwindow, I use the data to render the download details:

ready(){ //using vue js component
    let ditem = remote.getGlobal('ditems')
    console.log(ditem)// this not always reflect the values as above
    .....
 }

The problem here is, when I add 1 download, it works perfectly. But if I added 2 or more downloads, it start to show strange behavior, where the global variable in the renderer process not updated wheres in the main process, it shows proper download objects and the downloads running without error. I called it strange because it not always like that, sometime it works, sometime it’s not.
The global variables in the renderer process seems not always reflected the global variable value in the main process.

Did I missed something in the remote module??

Edit
I am using vue js for ui if this matter.


#2

I’m having a very similar issue. I’m making an IPC call from a render process to the main process to update a value on global:

// in render process:
ipc.send('create-template');

// in main process:
ipc.on('create-template', function(event) {
    let template = {
        uuid: utils.generateUUID(),
        name: "New Template",
        properties: {},
    }
    global.project.templates[template.uuid] = template;
    event.sender.webContents.send('template-created', template);
});

// in render process again trying to access new template
function handleEditTemplate(e) {
    state = 'template';
    currentTemplateUUID = $(this).closest('.panel').attr('uuid');
    let templates = electron.remote.getGlobal('project').templates;

    let template = templates[currentTemplateUUID]; // returns undefined

    templateEdit.find('#name').val(template.name);

    templateEdit.find('#list').empty();
    for (let property in template.properties) {
        if (template.properties.hasOwnProperty(property)) {
            addProperty(property);
        }
    }

    templateList.hide();
    templateEdit.show();
}

The function “handleEditTemplate()” executes normally the first time, but subsequent calls for newly added templates does not work. Logging the global object in main shows that it has been correctly added, but it doesn’t appear in the render process.

My gut is telling me that “getGlobal()” is caching the value or there is some behavior here that I am not aware of.


#3

Your gut feeling is correct, remote.getGlobal() caches the values it retrieves from the main process (see https://github.com/electron/electron/issues/5599). There are many gotchas with the remote module, which is why I’d suggest avoiding it whenever possible (it’s useful for accessing Electron built-ins that live in the main process, but anything involving callbacks, events, or globals is going to land you trouble sooner or later).


#4

Good to know! I ended up using a synchronous IPC call to achieve the same thing.