skip to Main Content

So, I struggled with this problem for 2 days, looking in the API documentation of Electron.js and various sites and you guys are my last hope:

Here are the 3 files related to the issue:

main.ts (not the entire file):

app.whenReady().then(() => {
  ipcMain.on("set-credentials", (event, args: object) => {
    encryptedCredentials = safeStorage.encryptString(JSON.stringify(args));
  });

  ipcMain.handle("get-credentials", async (event, args: null) => {
    const decryptedCredentials = await JSON.parse(
      safeStorage.decryptString(encryptedCredentials)
    );
    return decryptedCredentials;
  });

  createWindow();
});

preload.ts (entire file):

import { ipcRenderer, contextBridge } from "electron";

contextBridge.exposeInMainWorld("electronAPI", {
  setStoredCredentials: async (args: object) =>
    await ipcRenderer.send("set-credentials", args),
  getStoredCredentials: () => {
    ipcRenderer.invoke("get-credentials");
  },
});

Login.tsx (not the entire file):

const setStoredCredentials = async (e: any, service: string) => {
    e.preventDefault();
    window.electronAPI.setStoredCredentials({
      service,
      username: e.target[0].value,
      password: e.target[1].value,
    });
    setTimeout(() => {
      window.electronAPI.getStoredCredentials().then(
        (data: object) => { console.log(data); } //testing 

      )
    }, 1000)
  };

(the electron app features React)

So to solve the issue I tried using ipcMain.on and ipcRenderer.sendSync with event.returnValue, didn’t work either.
I get the following error with the current code:

caught TypeError: Cannot read properties of undefined (reading 'then')
 

and the other methods I tried either gave the same error or an undefined value.

2

Answers


  1. Chosen as BEST ANSWER

    just a small clarification:

    when I do a console.log() of the value to return in main.ts before returning it it works just fine.

    Also the cryptedCredentials var is declared as follows: let cryptedCredentials: Buffer;


  2. Two-way IPC needs async/await in the renderer process. IPC may spend a bit time. Without async/await, the original call just gets a Promise.

    Try to add await to both setStoredCredentials and getStoredCredentials.

    const setStoredCredentials = async (e: any, service: string) => {
        e.preventDefault();
        await window.electronAPI.setStoredCredentials({
          service,
          username: e.target[0].value,
          password: e.target[1].value,
        });
        setTimeout(() => {
          await window.electronAPI.getStoredCredentials().then(
            (data: object) => { console.log(data); } //testing 
    
          )
        }, 1000)
      };
    

    If the code above works, setTimeout can be removed.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search