3

I'm developing an Electron app with React and Typescript. The logic which the app requires is in the main.ts and passes the object to the renderer via IPC. How I learned does IPC serialize the objects and therefore lose it's functions and prototypes. Now my question: is there a way to have the same object (with it's type) om the renderer? I tried with Object.assign() but this returns the following error:

Uncaught Error: Cannot read properties of undefined (reading 'ReferenceDescription')

By the way I'm using the node-opcua package which exports the ReferenceDescription class. My code in the renderer to reassign the object looks like this:

import { ReferenceDescription } from 'node-opcua';
// [...]
window.electron.opcua.onNodeListChange(nodes => {
  let typedNode = Object.assign(ReferenceDescription, nodes[0]);
  // also tried: new ReferenceDescription()
}

Is there any way to get back the types in the renderer after IPC transfer?

Robin Aegerter
  • 457
  • 3
  • 16
  • Three problems with your approach: (1) `Object.assign()` expects the target of the operation to be the first parameter. (2) `Object.assign()` expects two or more *instances* as parameters, not a prototype. (3) `Object.assign()` is for [copying properties and values](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) between objects; it does not restore types, because it's only enumerating own properties of the source(s). Is your main process manipulating the object passed to the renderer or does the renderer do anything with the (typed) objects? – Alexander Leithner Jun 27 '22 at 08:44
  • (2): that's why I tried with the instance (see comment in code)... (3): This would actually work for the functions I guess (see my detailed goal below)... The main problem is, that the .toString() is prototyped in the ReferenceDescription-class. IPC serializes the object and loses all prototypes and functions. With Object.assign() I tried to restore the function on the node-object. So yes, I need the typed objects in the renderer. – Robin Aegerter Jun 27 '22 at 08:51
  • 1
    One common design pattern for this is to write a constructor that accepts the serialized (or plain-old-object/struct) values as argument. Therefore you can do `new ReferenceDescription(nodes[0])` and get a **new** (note: not the original object) object with all the values of the object you sent over IPC. The general topic for this in other languages is called object freezing and thawing (not to be confused with javascript's "Object.freeze" which is something completely different) – slebetman Jun 27 '22 at 08:53
  • 1
    Alternatively I've also seen people use a builder pattern for this with a static method instead of the constructor: `ReferenceDescription.from(nodes[0])`. The `.from()` static function will construct a new object and fills in all the correct values. There are quite a few examples of this style of code in javascript eg. `Buffer.from()` – slebetman Jun 27 '22 at 08:55
  • Thanks for the ideas so far. At the moment I think the (first) problem is somewhere else. Everytime I use ReferenceDescription in the renderer it says the same error I posted in the question. The package is installed in both node_modules-folders, so this shouldn't be a problem. (Using it in the main works fine; but not in the renderer.) – Robin Aegerter Jun 27 '22 at 09:07
  • Do you have`nodeIntegration` set to `true`? – midnight-coding Jun 28 '22 at 01:34

0 Answers0