hdw3
hdw3

Reputation: 951

How to add ipcRenderer from Electron to Angular? Attached variables from preload script are undefined

I am not sure how to use ipcRenderer in 'frontend' code of electron app. In the documentation I have found examples that are using require but I don't have require available on the frontend. (I am using angular to create 'frontend' side)

In the electron docs - https://www.electronjs.org/docs/tutorial/process-model#preload-scripts I have found an example how to attach variables from the main process to the window in renderer process but when I try to use attached variables I get undefined.

main.js

function createWindow() {
  win = new BrowserWindow({
    width: 800,
    height: 600,
    backgroundColor: "#ffffff",
    preload: './preload.js'
  });

  win.loadFile('dist/foobar/index.html') // I get index.html after building angular code

  win.on("closed", () => {
    win = null;
  });
}

app.on("ready", createWindow);

preload.js

const { contextBridge, ipcRenderer } = require("electron");
   
contextBridge.exposeInMainWorld("ipcRenderer", {ipcRenderer}); //exposing ipcRenderer to the window in renderer process 

electron service (angular code)

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class ElectronService {

  constructor() { }

  getIpcRenderer(){
    return (<any>window).ipcRenderer;
  }
}

angular component

export class FoobarComponent {

  constructor(private es: ElectronService) {}

  test(){
    console.log(this.es.getIpcRenderer()); // this logs as undefined
  }
}

My problem
In the code above you can see that test() prints undefined. Why is window.ipcRenderer undefined? I have also ran console.log(window) and I can't find ipcRenderer on the list of properties

Is there better way to expose ipcRenderer to my angular code? In the doc linked above they are saying

This feature is incredibly useful for two main purposes:

  1. By exposing ipcRenderer helpers to the renderer, you can use inter-process communication (IPC)
    to trigger main process tasks from the renderer (and vice-versa).
  2. [...]

I assume that contextBridge.exposeInMainWorld is the best way since it is in the documentation but please let me know if this is outdated or if there is simply a better way.


How I run my electron app

  1. I build angular code (ng build --prod)
  2. I start electron app by running electron . (main.js is the entry point)

Upvotes: 2

Views: 2993

Answers (1)

hdw3
hdw3

Reputation: 951

In case someone makes the same mistake:

preload should be in webPreferences instead of directly in BrowserWindow
wrong

win = new BrowserWindow({
    preload: './preload.js'
});

correct

win = new BrowserWindow({
    webPreferences:{
      preload: './preload.js'
    }
});

Upvotes: 3

Related Questions