When trying to get a message from ipcMain to ipcRenderer (without node integration and with contextIsolation), it's received but as undefined. Not only that, but if I were to reload the VueComponent (regardless of what change I make to it), the number of responses gets doubled.
For example, the first time I start my application, I get 1x undefined at a time every time I click the button. If I reload the component, I start getting 2x undefined every time I click the button. I reload again and get 4x undefined every time I click the button... and it keeps doubling. If I restart the application, it goes back to 1x.
SETUP
ElectronJS + VueJS + VuetifyJS has been set up as described here.
preload.js as per the official documentation.
import { contextBridge, ipcRenderer } from 'electron'
window.ipcRenderer = ipcRenderer
// Expose protected methods that allow the renderer process to use
// the ipcRenderer without exposing the entire object
contextBridge.exposeInMainWorld('ipcRenderer', {
send: (channel, data) => {
// whitelist channels
let validChannels = ['toMain']
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, data)
}
},
receive: (channel, func) => {
let validChannels = ['fromMain']
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`
ipcRenderer.on(channel, (event, ...args) => func(...args))
}
}
})
background.js (main process) as per the official documentation for the preload.js file. The omitted code via ... is the default project code generated upon creation.
...
const path = require('path')
const { ipcMain } = require('electron')
async function createWindow() {
// Create the browser window.
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
// Use pluginOptions.nodeIntegration, leave this alone
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
contextIsolation: true,
preload: path.join(__dirname, 'preload.js'),
},
icon: 'src/assets/icon.png',
})
ipcMain.on('toMain', (event, data) => {
console.log(data)
event.sender.send('fromMain', 'Hello IPC Renderer')
// The two lines below return 'undefined' as well in the 'ipcRenderer'
//win.webContents.send('fromMain', "Hello IPC Renderer")
//event.reply('fromMain', 'Hello IPC Renderer')
})
...
}
...
vue.config.js file:
module.exports = {
...
pluginOptions: {
electronBuilder: {
preload: 'src/preload.js',
}
}
}
main.js (renderer process) contains only the default project code generated upon creation.
VueComponent.vue
<template>
<div id="vue-component">
<v-btn @click="sendMessageToIPCMain()">
</div>
</template>
<script>
export default {
name: "VueComponent",
components: {
//
},
data: () => ({
myData: null,
}),
methods: {
// This works. I get 'Hello IPC Main' in the CMD console.
sendMessageToIPCMain() {
var message = "Hello IPC Main"
window.ipcRenderer.send("toMain", message);
}
},
mounted() {
window.ipcRenderer.receive('fromMain', (event, data) => {
// this.myData = data // 'myData' is not defined error
this.$refs.myData = data;
console.log('myData variable: ' + this.$refs.myData) // undefined
console.log(data) // undefined
})
},
}
</script>
The VueComponent.vue's mounted() has been set up as described here, though If I try to send the data to a variable using this.myData = data, I get an error saying that myData has not been defined - using this.$refs.myData works, though it's still undefined.
P.S. myData has not been defined error =/= undefined. The former is a proper error in red letters while the latter is as seen in the image above.
