Cannot read property 'require' of undefined - electron

I am creating an application to use mysql. I want to call a function from the main.js file. This main.js file is the main application file, just like the documentation. I saw an example of how to call this function:
const { remote } = require('electron');
const main = remote.require('./main');
main.saveUser();
But it gives the following error:
Uncaught TypeError: Cannot read property 'require' of undefined at app.js:4'
I believe it has updated and the way of calling has changed, can someone help me by sending the link to the documentation that talks about, please.

Solution is very easy. Just add webPreferences: {nodeIntegration: true, enableRemoteModule: true} in your BrowserWindow in main.js.
The code look like this:
win = new BrowserWindow({
width: 990,
height: 660,
title: "Okkhor52 Tools",
resizable: false,
frame: false,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true
}
});

Related

Windows: Electron notifications not showing the app logo but everywhere else it does

The app logo is properly shown everywhere else but in the notification section where it displays an empty logo
I know that you can add a custom image for the notification passing a icon property like so:
new Notification({
title: 'Test Notification',
body: 'This is a test notification',
icon: path.join(__dirname, 'icon.ico'),
});
But that's not the logo I want to change.
The app when built also shows the correct logo elsewhere:
I also added an icon property when creating the BrowserWindow like advised here.
const win = splashWindow = new BrowserWindow({
width: 320,
height: 320,
// more
icon: path.resolve(__dirname, 'icon.ico'),
});
Adding a
win.setIcon(path.resolve(__dirname, 'icon.ico');
doesn't work too.
This code is all in main.js.
And I've been checking the docs for the App class and there's a getFileIcon but it doesn't appear to be related to this.
May be related?
I have been able to modify the app name to 'Awesome App' via setAppUserModelId like so:
ipcMain.on('app-ready', () => {
if (process.platform === 'win32') {
// somehow also change logo here? can't find it in the docs
app.setAppUserModelId('Awesome app');
}
I call app.setAppUserModelId('xxxx') before new Notification and it works.
xxxx is your bundle id.

How can I access multiple instances of mainWindow in an Electron App?

How do I create a functioning electron app with multiple instances of the mainWindow? Here's a very simple app with a mainWindow that just has two buttons. One to create a new mainWindow instance, and one to close the current window.
// main.js
const { app, ipcMain, BrowserWindow } = require('electron')
let mainWindow;
function main () {
mainWindow = new BrowserWindow({
width: 500,
height: 400,
tabbingIdentifier: 'todoTab',
show: false,
webPreferences: {
nodeIntegration: true
}
})
mainWindow.loadFile('renderer/index.html');
mainWindow.once('ready-to-show', () => {
mainWindow.setTitle("Todo-" + mainWindow.id)
mainWindow.show();
})
mainWindow.mergeAllWindows();
}
app.on('ready', main);
ipcMain.on('newListWindow', main);
ipcMain.on('closeWindow', function(event){
mainWindow.close();
});
In the above file I set mainWindow as a global variable.
Adding a tabbingIdentifier property and chaining the mergeAllWindows() method will automatically create multiple tabs in the display if more than one window is opened.
Each mainWindow instance is assigned an id by Electron. If only one instance is open the id is 1. For simplicity I set the mainWindow title to be "Todo-" + the mainWindow.id (so Todo-1 for the first window, Todo-2 if I open a second).
When the newListWindow button is clicked the "main" function gets called creating a new instances of mainWindow.
When the closeWindow button is pressed the mainWindow instance is closed.
The HTML file with the two buttons (abbreviated to just the body element)
// renderer/index.html
<body>
<h1 class="text-center">Todo List</h1>
<button id="new-list-btn">New Todo List</button>
<button id="close-btn">Close List</button>
<script src="./index.js"></script>
</body>
The ipcRenderer. Listens for the button clicks and sends a message to main.js.
// renderer/index.js
const { ipcRenderer } = require('electron')
document.getElementById('new-list-btn').addEventListener('click', () => {
ipcRenderer.send('newListWindow');
});
document.getElementById('close-btn').addEventListener('click', () => {
ipcRenderer.send('closeWindow');
});
The above code will create multiple Todo windows and display them on different tabs. Each list title (Todo-1, Todo-2, etc) is displayed. The problem is, the last one opened is the only active one. So if I open three todos, then go to any one of them and click the close button, only the third window will close, regardless of which one I was in. Then the other two will throw an error if I try to close them saying the object was destroyed. Which makes sense. So how do I code this so if that whichever instance tab I am in is the one that I close. And when I close it the next tab I am in becomes the valid mainWindow object?
You may want to deal only with the focused BrowserWindow in 'closeWindow' callback
Use BrowserWindow.getFocusedWindow static method
ipcMain.on('closeWindow', function(event) {
const current = BrowserWindow.getFocusedWindow()
if (current) current.close()
})
Pergy's answer works as requested but I'll post this answer as well since it's what I'm actually using, and there's no other documentation on how to do this that I could find. The difference is small but this seems more direct:
ipcMain.on('closeWindow', function(event) {
mainWindow = BrowserWindow.getFocusedWindow();
mainWindow.close();
})

how do I remove menu bar from electron app

I know this has been asked but previous answers aren't working. This is my first electron app.
Here is my main.js
const { app, BrowserWindow } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win
function createWindow () {
// Create the browser window.
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
win.loadFile('index.html')
// Open the DevTools.
//win.webContents.openDevTools()
// Emitted when the window is closed.
win.on('closed', () => {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
win = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (win === null) {
createWindow()
}
win.setMenu(null);
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
I thought win.setMenu(null);would remove the menu bar but it does not. What do I need to do to completely remove this?
--The only think I've found that is sort of close is making the app frameless.
win = new BrowserWindow({
width: 800,
height: 600,
frame: false,
webPreferences: {
nodeIntegration: true
}
})
For Windows and Linux:
require('electron').Menu.setApplicationMenu(null);
Refer to https://electronjs.org/docs/api/menu#menusetapplicationmenumenu

Drag'n'Drop into Electron app is not allowed

I am trying to implement Drag'n'Drop functionality for users to easier upload their images. In browser the drop area works perfectly but Electron is preventing files to be even dropped into the app. Every time I try to drop a file cursor changes to the one shown below and nothing happens.
I thought maybe Electron had configs to disable dropping files by default due to popular complain but I couldn't find any solution.
The picture shows the drop area, but the same issue is all across the app.
Main.js:
const { app, BrowserWindow } = require('electron')
let win
function createWindow () {
win = new BrowserWindow({ width: 1000, height: 600, minWidth: 690, minHeight: 340 })
win.loadFile('index.html')
win.webContents.openDevTools()
win.on('closed', () => {
win = null
})
}
app.on('ready', createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (win === null) {
createWindow()
}
})
Ok. That wasn't fun. Looks like something actually broke. But after I restarted the console, Windows then reinstalled the project, Electron, and NPM it finally worked. The problem is now solved.

How to use require() in Electron?

I use for the first time electron and webchimera. I see this demo, but I don't want open in main window the player. I do not know good use electron so I try with a server that renders a index page and, after a button click, the player-page.
Client loads from server the index page:
//this is for webchimera
if (process.platform == 'win32')
process.env['VLC_PLUGIN_PATH'] = require('path').join(__dirname, 'node_modules/wcjs-prebuilt/bin/plugins');
const {app, BrowserWindow} = require('electron')
const path = require('path')
const url = require('url')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win
function createWindow () {
// Create the browser window.
win = new BrowserWindow({width: 800, height: 600})
// and load the index.html of the app.
win.loadURL("http://localhost:8888/")
// Open the DevTools.
win.webContents.openDevTools()
// Emitted when the window is closed.
win.on('closed', () => {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
win = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (win === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
The index page contains a link to player page, if it clicked the server responds with the player page.
The server is in nodejs.
Server run in localhost:8888 and it sends this html page:
<html>
<head>
<style>
body,html{ width: 100%; height: 100%; padding: 0px; margin:0px }
#player { width: 100%; height: 100% }
</style>
</head>
<body>
<div id="player"></div>
<script>
var wjs = require("wcjs-player");
var player = new wjs("#player").addPlayer({
autoplay: true,
wcjs: require('wcjs-prebuilt')
});
player.addPlaylist("http://archive.org/download/CartoonClassics/Krazy_Kat_- _Keeping_Up_With_Krazy.mp4");
</script>
</body>
</html>
But I obtain this error:
cannot find module wcjs-player
How can I fix this?
PS:
I use a server only because I wrote it for a webapp before I decided to use electron. It not necessary. I can remove the server and use only the client.
That means the module wcjs-player is not installed. Run npm install wcjs-player in your console/terminal to install it, that must help and also, you might wanna take a look at this

Resources