Electron API is not working. I'm getting the following error. I see that the sendPin function is not working.
Uncaught TypeError: Cannot read properties of undefined (reading 'sendPin')
at HTMLDocument.handlekeyUp (pin-pad:86:28)
pin-pad:61 Uncaught TypeError: Cannot read properties of undefined (reading 'sendPin')
at HTMLDivElement.<anonymous> (pin-pad:61:28)
It was working until I had added following line of code, for this reason I suspect it may be the main reason.
if (13 === e.keyCode) { window.electronAPI.sendPin(Pin);
index.html is as following.
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="pinpad.css" />
<meta charset="UTF-8" />
<title>Electron Test - Pin Pad</title>
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self' 'unsafe-inline';"
/>
</head>
<body>
<div id="container">
<div id="wrapper">
<input type="password" id="display" disabled />
<div id="pin-pad">
<div data-number="1">1</div>
<div data-number="2">2</div>
<div data-number="3">3</div>
<div data-number="4">4</div>
<div data-number="5">5</div>
<div data-number="6">6</div>
<div data-number="7">7</div>
<div data-number="8">8</div>
<div data-number="9">9</div>
<div>Enter</div>
<div data-number="0">0</div>
<div>Clear</div>
</div>
</div>
</div>
</body>
<script>
let display = document.getElementById("display");
let validKeys = [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"0",
"Enter",
"Clear",
];
let pin = "";
document.getElementById("pin-pad").addEventListener("click", (event) => {
if (!validKeys.includes(event.target.innerText)) {
return;
}
if (event.target.innerText === "Enter") {
window.electronAPI.sendPin(pin);
return;
}
if (event.target.innerText === "Clear") {
pin = display.value = "";
return;
}
pin = pin event.target.innerText;
display.value = "*".repeat(pin.length);
});
///tests
const handlekeyUp = function (e) {
e.stopPropagation();
const input = document.getElementById("display");
console.log(input, e.key, input.value);
var reg = new RegExp("^[0-9]$");
const number = document.querySelector(`[data-number="${e.key}"]`);
if (reg.test(e.key)) input.value = e.key;
if (number) number.style.backgroundColor = "#fff";
if (13 === e.keyCode) {
window.electronAPI.sendPin(Pin);
}
};
const handleKeyDown = (e) => {
const number = document.querySelector(`[data-number="${e.key}"]`);
if (!number) {
return;
}
number.style.backgroundColor = "#eee";
};
document.addEventListener("keyup", handlekeyUp);
document.addEventListener("keydown", handleKeyDown);
</script>
</html>
main.js
const electronApp = require("electron").app;
const electronBrowserWindow = require("electron").BrowserWindow;
const electronIpcMain = require("electron").ipcMain;
const nodePath = require("path");
// Prevent garbage collection
let window;
function createWindow() {
const window = new electronBrowserWindow({
fullscreen: true,
show: false,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: nodePath.join(__dirname, "preload.js"),
},
});
window.loadFile("pin-pad.html").then(() => {
window.show();
});
return window;
}
electronApp.on("ready", () => {
window = createWindow();
});
electronApp.on("window-all-closed", () => {
if (process.platform !== "darwin") {
electronApp.quit();
}
});
electronApp.on("activate", () => {
if (electronBrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
// ---
electronIpcMain.on("pin", (event, pin) => {
// Simple check of pin validity
if (pin === "1234") {
window.loadFile("sales.html");
}
});
preload.js is as following, I have also added just incase.
const contextBridge = require("electron").contextBridge;
const ipcRenderer = require("electron").ipcRenderer;
contextBridge.exposeInMainWorld("electronAPI", {
sendPin: (pin) => {
ipcRenderer.send("pin", pin);
},
});
CodePudding user response:
In reference to index.html
, within the if (13 === e.keyCode) { ... }
statement, the argument of the window.electronAPI.sendPin(...);
call is of the incorrect case. Instead of Pin
, it should be pin
.
That said, pin
is not updated within your const handlekeyUp = function (e) { ... }
function, so when "Enter" (or "Return") is pressed, it can't send an updated pin
to your render process.
Looking closer at your JavaScript code contained within your index.html
file:
- There would be no need to stop event propagation.
- Regex's can be tricky things and hard to implement at times. Only use them if you really need to.
- It appears that you are use the
#display
value instead of using the already definedpin
variable to build yourpin
.
Continuing to use the already defined pin
variable allows you to use both the mouse and the keyboard together (if the user really wants to) to enter a pin.