1

TL;DR: I need to inject some JavaScript into a BrowserView in Electron using executeJavaScript. This code needs to be class. How can I stringify the class?

I found out that you can stringify functions using +.

const fn = function() {
  console.log('Hello');
};
const functionToText = '' + fn;
console.log(functionToText);
// function() {
//   console.log('Hello');
// }
*/

But my problem is, how can you stringify classes? I need the string version of the following object created from the class with new to inject it.

class Person {
  constructor({ name }) {
    this.getName = () => name;
  }
}
const person = new Person({ name: 'John'});
const str = // somehow stringify person here
console.log(str);
// the person object
view.webContents.executeJavaScript(`window.person = ${str}`);

Edit:

Here is how I ended up implementing it based on the accepted answer:

view.webContents.executeJavaScript(
  `window.person = new ${str}({ name: 'John' })`
);
J. Hesters
  • 13,117
  • 31
  • 133
  • 249

1 Answers1

1

You had the solution in your question. The same approach that works for functions works for classes too.

class Person {
  constructor({ name }) {
    this.getName = () => name;
  }
}
const str = '' + Person;
console.log(str);

Updated in response to additional data in question. You can't serialize an object and make it cross execution boundaries because it is no longer data at that point, but instead is running in memory.

One approach you could take is invoke all of the code inside the call to executeJavaScript

For example:

view.webContents.executeJavaScript(`
class Person {
  constructor({ name }) {
    this.getName = () => name;
  }
}

window.person = new Person({name: 'John'});
`);

Or alternatively

view.webContents.executeJavaScript(`
(function() {
    class Person {
      constructor({ name }) {
        this.getName = () => name;
      }
    }

    window.person = new Person({name: 'John'});
})();
`);
Steve
  • 2,205
  • 1
  • 21
  • 28
  • I'm sorry for not clarifying. I want to stringify the class **after** calling `new`. – J. Hesters Sep 18 '19 at 20:27
  • You can't transfer the object, because at that point it's no longer "just data". Could you execute the entire thing in the function call rather than trying to cross execution boundaries? view.webContents.executeJavaScript(`class Person { ...} window.person = new Person({name: John})`); Or wrap it in an IIFE if the code is expected to be a single expression. – Steve Sep 18 '19 at 20:31
  • 1
    Thank you very much! I amended my question with how I implemented it, because in my real application I'm importing the class. – J. Hesters Sep 18 '19 at 20:41