When the app is launched, I am trying to send some data from main.js to renderer.js so that renderer.js can begin rendering some elements. I have no idea what is going wrong, but it seems communication breaks down at preload.js. I have checked Electron's documentation and my code looks fine. I have no problem communicating from renderer.js to main.js to renderer.js, but communicating from main.js to renderer.js does not want to work. Any help would be very much appreciated.
As per @elichen's instruction, I tested ipcRenderer.on('data:dataList',()=>console.log('called')) at the top of preload.js and this is logging... What the heck is going on here?
// main.js
async function readJSON(filePath) {
try {
const data = await fs.readFile(filePath, 'utf-8')
return JSON.parse(data)
} catch (error) {
if (error.code === 'ENOENT') return []
else throw error
}
}
async function loadData() {
try {
const
configFilePath = path.join(app.getPath('userData'), 'List of Data Points.json'),
dataList = await readJSON(configFilePath)
if (dataList.length) {
console.log(dataList.length) //## THIS LOGS CORRECTLY ##//
mainWindow.webContents.send('data:dataList', dataList)
console.log('Sent data from main.js') //## THIS LOGS TO MAIN.JS CONSOLE ##//
}
} catch (error) {
console.error('Error reading configuration file:', error)
}
}
app.whenReady().then(()=>{
createWindow()
loadData()
...
// preload.js
ipcRenderer.on('data:dataList',()=>console.log('called')) //## THIS LOGS ##//
contextBridge.exposeInMainWorld('myAPI',
{
onDataListReady: (callback) => ipcRenderer.on('data:dataList', (_event, value) => {
console.log('Why does this not work?') //## THIS DOES NOT LOG ##//
return callback(value)
}),
...
// renderer.js
window.myAPI.onDataListReady((value) => {
console.log(value) //## THIS DOES NOT LOG TO BROWSER CONSOLE ##//
try {
dataList.forEach(it=>console.log(it))
} catch (error) {
console.error('Error in onDataListReady:', error)
}
})
the reason
ipcRenderer.on('data:dataList',...not called is because the order of thingscreateWindow()at this step the preload is loading but the listener fordata:dataListnot yet created. (its created by callingonDataListReadywhich calls later)loadData()at this step the main send to preload the event but no one listening to that eventthe render called
onDataListReadywhich only now create the listener.the fix to that problem is normally subject to implementation of the app. a small fix can be by calling
loadDataafter all dom and js loaded for example usingdid-finish-loadevent like below