MagicMirror Forum

    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unsolved
    • Solved
    • MagicMirror² Repository
    • Documentation
    • Donate
    • Discord

    How to send a function as payload of socket notification?

    Development
    socket notification notifications payload nodehelper
    3
    5
    465
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • N
      ngnijland last edited by

      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?

      S ? 2 Replies Last reply Reply Quote 0
      • S
        sdetweil @ngnijland last edited by

        @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

        Sam

        Create a working config
        How to add modules

        1 Reply Last reply Reply Quote 0
        • N
          ngnijland last edited by

          @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?

          1 Reply Last reply Reply Quote 0
          • ?
            A Former User @ngnijland last edited by A Former User

            @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.

            N 1 Reply Last reply Reply Quote 0
            • N
              ngnijland @Guest last edited by ngnijland

              @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.

              https://github.com/ngnijland/MMM-text-clock/pull/2

              1 Reply Last reply Reply Quote 0
              • 1 / 1
              • First post
                Last post
              Enjoying MagicMirror? Please consider a donation!
              MagicMirror created by Michael Teeuw.
              Forum managed by Paul-Vincent Roll and Rodrigo Ramírez Norambuena.
              This forum is using NodeBB as its core | Contributors
              Contact | Privacy Policy