2023-05-27

How to run a function in a singleton file only when electron main process is ready

I am using electron + vue, in my vue files, there is a file called globals.ts which is a file that exports global variables for all my vue files to use, it is a singleton file, I am trying to get it to communicate with electrons main process to fetch the user's machine IP address, however, there are errors occuring because apparently the main process is not finished loading before globals.ts function runs, meaning the ipcRenderer function is invoked before the main has the API available. How do i get it to wait for the main process to finish loading first so i can safely invoke a function and get a result?

//electron/main/main.ts
async function createWindow() {//...code to create window here}
    
ipcMain.handle("getMachineIPv4", (e, arg) => {
  console.log("getting ipv4");
  const interfaces = os.networkInterfaces();
  for (const interfaceName in interfaces) {
    const interfaceInfo = interfaces[interfaceName];
    for (const info of interfaceInfo) {
      if (info.family === "IPv4" && !info.internal) {
        return info.address;
      }
    }
  }
});

.

//electron/preload/preload.ts
    contextBridge.exposeInMainWorld("ipcRenderer", {
  send: (channel: string, data: string) => {
    // whitelist channels
    let validChannels = ["OpenFolder"];
    if (validChannels.includes(channel)) {
      ipcRenderer.send(channel, data);
    }
  },
  receive: (channel, func) => {
    let validChannels = ["fromMain"];
    if (validChannels.includes(channel)) {
      // Deliberately strip event as it includes `sender`
      ipcRenderer.on(channel, (event, ...args) => func(...args));
    }
  },
  invoke: (channel, arg) => {
    //invoke is an async function with a promise
    console.log(channel + " invoked");
    let validChannels = ["asyncFunc", "getMachineIPv4"];
    if (validChannels.includes(channel)) {
      // Deliberately strip event as it includes `sender`
      return ipcRenderer.invoke(channel, arg);
    }
  },
});

.

//inside src folder /assets/globals.ts

 export const address: Promise<string> = (async () => {
  try {
    const hostname: string = await window.ipcRenderer.invoke("getMachineIPv4", "please work");
    const firstThreeNumbers = hostname.split(".")[0];
    const portNumber = "3000";
    const subnet = "10";
    if (firstThreeNumbers === "123") {
      return `123.123.1111.${subnet}:${portNumber}`;
    } else if (firstThreeNumbers === "101") {
      return `123.123.111.${subnet}:${portNumber}`;
    } else if (hostname == "localhost") {
      // Default, usually localhost
      return `123.123.111.${subnet}:${portNumber}`;
    } else {
      console.error("ip address not found");
      return "error";
    }
  } catch (error) {
    console.error("Failed to get address:", error);
    return "error";
  }
})();


No comments:

Post a Comment