bartbutenaers / node-red-contrib-blockly

A Node Red node for visual programming a function using Blockly
Apache License 2.0
89 stars 22 forks source link

Support 'environment' block in other blocks #71

Closed bartbutenaers closed 3 years ago

bartbutenaers commented 3 years ago

We have introduced a new "environment" block to get environment variables:

image

I have extended the code generator of the above node_object_get block to make sure the correct javascript code will be generated:

env.get('PATH');

Remark: the "environment" block returns currently returns an object. However it should return a string, because - in contradiction to a context memory variable - an environment variable value is always a string.

Moreover some other changes need to be done to fully support this new "environment" block:

  1. When the "HAS" or "REMOVE" options are selected in the node_object_get block, then the "environment" block should be rejected as input (since we cannot remove environment variables). image

  2. The "node_object_set" block should not accept the "environment" block as input, since it is NOT possible to set environment variables: image

@jsccjj: Not sure how to implement such a conditional type check. Feels a bit overkill to implement our own custom type checker (like here), but I don't know any other way to solve this. Do you have any proposals perhaps?

Thanks! Bart

jsccjj commented 3 years ago

@bartbutenaers

I think there are two possible options:

  1. change the output type of the environmental block from "Object" to, for example, "Env"(or something else). Then add "Env"(or something else) on input check of "get" of node_object_get block like below image image Since the output type of the environmental block is "Env", the node_object_set should reject the block.

  2. create a new independent environmental block which output string and does not use node_object_get block

I hope this would help.

bartbutenaers commented 3 years ago

@jsccjj ,

  1. Option 1: I had also thought about this. But the problem is then still in the node_object_set block: it needs to accept the "Env" type for the GET option, but not for the HAS and REMOVE options.

  2. Option 2: I think that is the way to go. That I didn't think about that myself. The environment variables are completely different from the flow/node/global memory variables. So better to have an environment block similar to the node_object_get block. Then we don't need to write hacks in the context memory related blocks.

Thanks for sharing your opinion!!!!!!

bartbutenaers commented 3 years ago

@cymplecy,

I have pushed a new version of the "environment" block to Github. This can be much easier integrated with other blocks, without dirty hacks.

It now looks like this (which returns a String):

image

Example flow:

image

[{"id":"6f9044a0.b3870c","type":"Blockly","z":"c2a7925b.6e143","func":"msg['payload'] = (env.get('PATH'));\nnode.send([msg]);\n\nenv.get();\n","workspaceXml":"<xml xmlns=\"https://developers.google.com/blockly/xml\">\n  <block type=\"node_object_set\" id=\"gX/eh*PQB7$|#s[cv?qF\" x=\"-662\" y=\"-712\">\n    <value name=\"object_field\">\n      <shadow type=\"node_msg\" id=\"Q@l{i.!VToOzB|awKfkU\"></shadow>\n    </value>\n    <value name=\"field_name\">\n      <shadow type=\"text\" id=\"y[l*wG~*rfPtoU{T~Ggk\">\n        <field name=\"TEXT\">payload</field>\n      </shadow>\n    </value>\n    <value name=\"value_field\">\n      <shadow type=\"text\" id=\"0f6:Op^1?@z=$0X,?Hkz\">\n        <field name=\"TEXT\"></field>\n      </shadow>\n      <block type=\"node_env\" id=\"O4w@-%;+!bj[x{dE-yG%\">\n        <value name=\"VARIABLE_NAME\">\n          <shadow type=\"text\" id=\"ezp+=#vN0?M):f`#W#rw\">\n            <field name=\"TEXT\">PATH</field>\n          </shadow>\n        </value>\n      </block>\n    </value>\n    <next>\n      <block type=\"node_send\" id=\"Yoqo0*^[cs89^n:s:mB:\">\n        <field name=\"OUTPUT_NR\">1</field>\n        <value name=\"MESSAGE_INPUT\">\n          <shadow type=\"node_msg\" id=\"54X^[E^pMXOTtqY3prub\"></shadow>\n          <block type=\"node_msg\" id=\"2pz7$WcP#?EYH`4,t}rO\"></block>\n        </value>\n      </block>\n    </next>\n  </block>\n  <block type=\"node_env\" id=\"mG,huw9)S!~YPzS091d=\" x=\"-112\" y=\"-62\"></block>\n</xml>","outputs":1,"blocklyConfig":"d7a036fa.2c0298","name":"","x":420,"y":520,"wires":[["23f77ae.7ac7086"]]},{"id":"bb11da23.5f7ff8","type":"inject","z":"c2a7925b.6e143","name":"Get environment variable","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":210,"y":520,"wires":[["6f9044a0.b3870c"]]},{"id":"23f77ae.7ac7086","type":"debug","z":"c2a7925b.6e143","name":"Environment variable","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":620,"y":520,"wires":[]},{"id":"d7a036fa.2c0298","type":"blockly-config","showTrashcan":true,"allowComments":true,"showZoomControl":true,"toolboxPosition":"left","renderer":"geras","name":"Left"}]

I assume you have an opinion about this ;-)

cymplecy commented 3 years ago

Excellent :)

It lets me replace a function node that I use inside a subflow, as this was one of the few things I needed the JavaScript block for :)

image

image

image

bartbutenaers commented 3 years ago

Looks like this new block is ready for the beta version, so I'm going to close this issue.