electron: got error: ipc.send is not a function

Hello, I am trying to use ipc to forward a globalShortcut event for a media key. But I get ipc.send is not a function.

  • OS: OSX Maverick
  • Electron: 0.31.1

This code will make it easier to understand:

// MAIN process
var ipc = require('ipc')
var globalShortcut = require('global-shortcut')
...
  globalShortcut.register('MediaPlayPause', function () {
    ipc.send('playPause', 'togglePause')
  })
// WINDOW process
var ipc = window.require('ipc')
...
ipc.on('playPause', function () {
  console.log('playPause pressed')
})

If I console.log(ipc) I get:

EventEmitter {
  domain: null,
  _events:
   { ATOM_BROWSER_REQUIRE: [Function],
     ATOM_BROWSER_GLOBAL: [Function],
     ATOM_BROWSER_CURRENT_WINDOW: [Function],
     ATOM_BROWSER_CURRENT_WEB_CONTENTS: [Function],
     ATOM_BROWSER_CONSTRUCTOR: [Function],
     ATOM_BROWSER_FUNCTION_CALL: [Function],
     ATOM_BROWSER_MEMBER_CONSTRUCTOR: [Function],
     ATOM_BROWSER_MEMBER_CALL: [Function],
     ATOM_BROWSER_MEMBER_SET: [Function],
     ATOM_BROWSER_MEMBER_GET: [Function],
     ATOM_BROWSER_DEREFERENCE: [Function],
     ATOM_BROWSER_GUEST_WEB_CONTENTS: [Function],
     ATOM_SHELL_NAVIGATION_CONTROLLER: [Function],
     ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER: [Function],
     ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST: [Function],
     ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST: [Function],
     ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST: [Function],
     ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE: [Function],
     ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY: [Function],
     ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN: [Function],
     ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE: [Function],
     ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD: [Function],
     ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE: [Function],
     ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE: [Function],
     ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD: [Function],
     ATOM_SHELL_GUEST_WINDOW_MANAGER_GET_GUEST_ID: [Function] },
  _eventsCount: 26,
  _maxListeners: undefined }

Not sure what I am doing wrong.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 17 (5 by maintainers)

Most upvoted comments

Suggestion: Make invoking ipc.send() from main process throw an informative error.

@dkfiresky I found a solution. I mistakenly thought that the ipc module could be used to send events from main process to a renderer process. Instead, one must use the webContents.send method.

Regarding your code, all examples in the documentation show that ipc is required without the remote module.

In the end I had to do this:

// MAIN process
var globalShortcut = require('global-shortcut')
win = new BrowserWindow({ width: 960, height: 600 })
...
  globalShortcut.register('MediaPlayPause', function () {
    win.webContents.send('playPause')
  })
// WINDOW process
var ipc = window.require('ipc')
...
ipc.on('playPause', function () {
  console.log('playPause pressed')
})

But I still don’t understand why “ipc.send is not a function”. Thank you for helping.

But I still don’t understand why “ipc.send is not a function”.

@AoDev Where would it send to?

I don’t see how this is an issue.

You are trying to call a function that doesn’t exist, and can’t be implemented?

This just threw me off big time. Also had the ipc.send is not a function error.

So I googled around and found that there was now this ipcMain thing. Required that and still the same error. Really confused me because I thought to myself ‘well now I am using the thing to send from the main process, hell I am even sure it is the main process’. Only after reading through this did I realize how it works.

I mean it makes perfect sense that the main process catering to many rendering processes need to know which one to send to. But it still seems that there could be a better error message here.

Hi, although it was not my intention to turn this into a feature request, all of you have given interesting ideas.

As a developer (who did not read the docs well enough, hence this issue), I wish I had a simple stream of events that can be used by all windows and the main process. Whether it is ipc or another module, I wish I could simply do:

// listen from windows (renderer) or main process
var mainStream = require('main-stream')
mainStream.on('someEvent', function(event) {
  doSomething(event)
})
// emit from windows (renderer) or main process
var mainStream = require('main-stream')
var payload = 'some data'
mainStream.emit('someEvent', payload)

I think it’s quite simple, especially to synchronise multiple windows if necessary.

Regarding ipc.send in the main process, whether it ends up being there (with targetWin property) or not, I wish I had at least a descriptive error message like @skhameneh said 😃

@AoDev There is exactly 1 main process, and potentially many render processes. When you’re in the main process you can’t just do ipc.send because it can’t know which window you want to send to. So instead you must specify which window you want to send your message to by using win.webContents.send or in the ipc event handler there is a event.sender which you can also send messages back to.

But that’s why there is no send on the ipc module in the main process. Arguably it could be:

ipc.send = function (w, m, a) {
  w.webContents.send(m, a);
};

ipc.send(browserWindow, 'message', args);

But that is somewhat redundant.