Read the statement by Michael Teeuw here.
How to send a function as payload of socket notification?
-
Hello,
When I receive a socket notification in my
node_helper.js
file I want to sent a socket notification with an object containing a function as value of one of its keys. Like this:const NodeHelper = require('node_helper'); const someFunction = require('./someFunction'); module.exports = NodeHelper.create({ start: function () { console.log('Start node helper'); }, socketNotificationReceived: function (notification) { if (notification === 'FOO') { this.sendSocketNotification('FOO', { bar: someFunction }); } }, });
However, when I receive this notification inside my main module file the function is not present in the payload:
socketNotificationReceived: function (notification, payload) { if (notification === 'FOO') { console.log(payload.bar); // This logs 'undefined' } },
Any other values (object, arrays, etc) I pass in the payload are received correctly.
Does somebody know why the function I pass with the payload is
undefined
when I receive the socket notification in my main module file? -
@ngnijland I think u have to send the entire function in the packet. It can’t contain the address of anything on the other side
-
@sdetweil thanks for your reply!
I don’t think I completely understand you. What do you mean with “send the entire function”? Do you mean I can’t import a reference? And should write out the function in the
node_helper.js
file? -
@ngnijland
Impossible in the current MM legacy structure.
those processes are separated and can not share function.2 reasons;
- The function itself cannot be transferred through socket (JSON doesn’t allow it)
- If the function depends on some dependencies, it will lose them.
Anyway, if the function itself is somehow simple and has no dependency, there could be some trick.
var originalPayload = { "something": "hello, world", "someFunc" : (value) => { console.log(value) return value } } originalPayload.someFunc("Original Execution.") let replacer = (key, value) => { if (typeof value == "function") { return "__FUNC__" + value.toString() } return value } // Encode function in payload object var encodedPayload = JSON.stringify(originalPayload, replacer, 2) console.log("----") console.log(encodedPayload) console.log("----") // encodedPayload will have; // { // "something": "hello, world", // "someFunc": "__FUNC__(value) => {\n console.log(value)\n return value\n }" // } // Now you can transfer this string as payload of socketNotification. // this.sendSocketNotification("SOME_EVENT", encodedPayload) // ... // Let's assume you got a payload through socketNotification var receivedPayload = encodedPayload let reviver = (key, value) => { if (typeof value === 'string' && value.indexOf('__FUNC__') === 0) { value = value.slice(8) let functionTemplate = `(${value})` return eval(functionTemplate) } return value } var revivedPayload = JSON.parse(receivedPayload, reviver) revivedPayload.someFunc("Function is revived.")
CAUTION
If the function requires dependencies (node modules, injected Object, references out of scope, …) those will be lost and it will cause an error. -
@Sean
Ah ofcourse, thanks for the explanation!My function does not have dependencies. I’ll use good old
eval
to fix this!My use case is that I need to use a different function based on the language setting of the mirror. These functions live in a separate folder and I import them in the
node_helper.js
file (together with some other arrays and objects I need based on language). For now I’ll use this solution, maybe in the future I build in a build step in my module so I can import the files directly into my main module file.