Home > Net >  Electron API not working after keyCode function added
Electron API not working after keyCode function added

Time:06-25

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:

  1. There would be no need to stop event propagation.
  2. Regex's can be tricky things and hard to implement at times. Only use them if you really need to.
  3. It appears that you are use the #display value instead of using the already defined pin variable to build your pin.

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.

Use of enter image description here

  • Related