0

Building my first electron app and I'd like the workflow to be as follows:

mainWindow opens -> user clicks 'open' button -> 2nd window opens -> user enters input/hits submit -> mainWindow opens back up displaying user input

Below is my app.on('ready') from my main.js. The application startup (win.loadURL) works fine, as does the open-new-window event. The weirdness comes in the input-broadcast.

When the user enters input in the second window, the main window will re-open. However, the text in the console.log in the input-broadcast does not appear, and the input-received never fires in the main window's renderer.

Not sure what I'm doing wrong, however I may be using the wrong design pattern as well. Any help would be greatly appreciated!

main.js

const {app, BrowserWindow, ipcMain, remote} = require('electron');
const url = require('url');
const path = require('path');
const countdown = require('./countdown');

let win;
const windows = [];

app.on('ready', () =>{
console.log('app ready');

ipcMain.on('open-new-window', () =>{
    console.log('trying to open window');
        win.loadURL(url.format({
            pathname: path.join(__dirname, 'enterValue.html'),
            protocol: 'file:',
            slashes: true
        }));
});

ipcMain.on('input-broadcast', (evt, data) =>{
    console.log('input-broadcast happened in main');
    win.webContents.send('input-received', data);
    win.loadURL(url.format({
        pathname: path.join(__dirname, 'index.html'),
        protocol: 'file:',
        slashes: true
    }));      
});

win = new BrowserWindow({width: 800, height: 600});
win.loadURL(url.format({
    pathname: path.join(__dirname, 'index.html'),
    protocol: 'file:',
    slashes: true
}));
win.on('closed', () =>{
    console.log('closed');
    win = null;
});
})

renderer.js (assoc. with the index.html)

console.log('from renderer1');

const {ipcRenderer} = require('electron');

document.getElementById('start').addEventListener('click', ()=>{
    ipcRenderer.send('open-new-window');
    console.log('window button clicked');
});

ipcRenderer.on('open-new-window', (evt, count) =>{
    document.getElementById('userInput').innerHTML(count);
});

ipcRenderer.on('input-received', (evt, data) =>{
    console.log('input received');
    console.log(evt);
    console.log(data);
});

renderer2.js (assoc. with the user enterValue.html)

console.log('from renderer2');

const {ipcRenderer} = require('electron');

document.getElementById('submitButton').addEventListener('click', (evt, input)=>{
    var input = document.getElementById('randomInput').value;
    ipcRenderer.send('input-broadcast', input);
});

index.html

  <!DOCTYPE html>
  <html>
  <head>
        <meta charset="UTF-8">
        <title>Hello World!</title>
  </head>
  <body>
        <h1>Hello World!</h1>
        <p>Your input was <span id="userInput"></span><p>
        <button id="start">Open</button>
        <script>require('./renderer')</script>
  </html>

enterValue.html

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <p>Enter a name</p>
    <input type="text" id="randomInput" placeholder="enter a value"/>
    <button id="submitButton">Submit</button>
    <script>require('./renderer2.js')</script>
</body>
</html>
NealR
  • 10,189
  • 61
  • 159
  • 299

1 Answers1

1

Your call order is not right when sending input back to renderer.js. You call

win.webContents.send('input-received', data)

when index.html is not yet re-loaded into win!

To fix this you should swap the calls and make sure that the content is ready when you send ipc message

ipcMain.on('input-broadcast', (evt, data) => {
    console.log('input-broadcast happened in main')
    win.loadURL(url.format({
        pathname: path.join(__dirname, 'index.html'),
        protocol: 'file:',
        slashes: true
    }))
    win.webContents.once('dom-ready', () => {
        win.webContents.send('input-received', data)
    })
})
pergy
  • 5,285
  • 1
  • 22
  • 36