Using IPC in Angular - marcialwushu/angular-electron GitHub Wiki

Using IPC in Angular to communicate with the main process

On the angular side, we want to encapsulate that functionality inside of a simple service.

So let’s create a file service using the angular-cli.

ng generate service file

Now, we need to get the other part of the communication channel. For that, we need an object called ipcRenderer. This object is part of the electron package.

Because we want our application to be able to run without electron (in a browser) as well, we can’t just import electron. That wouldn’t run in a browser.

But we need that object from the electron package, so how do we get that?

A simple workaround

The solution is a method called require that electron injects into the window object at runtime. With that, we can import the required object.

And because we can check that require-method for null (as it does not exist in the browser window) we are still compatible with the web.

TS src/app/file.service.ts
import { Injectable } from '@angular/core'
import { IpcRenderer } from 'electron'

@Injectable({
  providedIn: 'root',
})
class FileService {
  private ipc: IpcRenderer

  constructor() {
    if ((<any>window).require) {
      try {
        this.ipc = (<any>window).require('electron').ipcRenderer
      } catch (error) {
        throw error
      }
    } else {
      console.warn('Could not load electron ipc')
    }
  }
}

You might notice that we are importing IpcRenderer at the top. That is just the type and does not contain the actual logic.

The getFiles method

Now that we have our ipc-object, we can start communicating with our main process.

We do so by creating a method called getFiles that handles all the IPC communication for us and gives back the result.

TS src/app/file.service.ts
async getFiles() {
    return new Promise<string[]>((resolve, reject) => {
      this.ipc.once("getFilesResponse", (event, arg) => {
        resolve(arg);
      });
      this.ipc.send("getFiles");
    });
  }

Again, we are defining a listener that is listening on the “getFilesResponse” channel. Because we do so by using the “once” method, it will unsubscribe itself after the first message.

Only after that, we send a request message on the channel “getFiles” to our main process.

Please be aware that this is a small example that should not be used in production as it can result in the application waiting forever if the main process does not respond. A production-ready function would need some type of timeout.

Also, you would probably give every request an id, to identify which request got what answer.

Finally, you can use that service now anywhere in your application just like a normal service.

⚠️ **GitHub.com Fallback** ⚠️