Is it possible to edit a variable block within the Javascript generator code?

70 views
Skip to first unread message

Amber

unread,
Jun 23, 2025, 2:02:29 PM6/23/25
to Blockly
Hello! I'm new to Blockly and am a beginner programmer. I'm currently trying to edit the value of a variable block within the Javascript generator.

BLOCK DEFINITION 
const key_assignment = {
init: function() {
this.appendDummyInput()
.appendField("private key var")
.appendField(new Blockly.FieldVariable("prvKey"), "PRV");
this.appendDummyInput()
        .appendField("public key var")
        .appendField(new Blockly.FieldVariable("pubKey"), "PUB");
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setOutput(true, "String");
this.setTooltip('Assigns generated RSA keys to private and public key variables');
    this.setHelpUrl('');
    this.setColour(225);
    }
    };
    Blockly.common.defineBlocks({list_to_vars : list_to_vars });

JAVASCRIPT GENERATOR
javascript.javascriptGenerator.forBlock['key_assignment'] = function(block) {
const varPrv = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('PRV'), Blockly.Variables.NAME_TYPE);
  const varPub = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('PUB'), Blockly.Variables.NAME_TYPE);

const code = `
rsaKeypair = KEYUTIL.generateKeypair("RSA", 1024);
${varPrv} = KEYUTIL.getPEM(rsaKeypair.prvKeyObj, "PKCS8PRV");
${varPub} = KEYUTIL.getPEM(rsaKeypair.pubKeyObj);
`;
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
    };

The function generates a pair of RSA keys. Then, it's supposed to assign the private and public keys to their respective variable blocks in the global Blockly space (these variable blocks are named prvKey and pubKey).

However, after running the code, it simply prints the contents of the private and public keys separately; then, when I try to print the contents of prvKey and pubKey variables, it returns "undefined."

Thus, it seems their values were never actually set, but I thought the lines with ${varPrv} and ${varPub} were updating the values of the variable blocks?

Is it even possible to update the value of a Blockly variable in the generator code, or am I just going about it the wrong way?

Thank you in advance!

(Not sure if it's relevant, but here are my injection and execution blocks.)

INJECTION
    window.addEventListener('load', () => {
    window.workspace = Blockly.inject('blocklyDiv', {
       toolbox: document.getElementById('toolbox'),
       scrollbars: true
      });
    });

EXECUTION
    function runCode() {
      try {
        const code = Blockly.JavaScript.workspaceToCode(window.workspace);
        const result = eval(code);
        document.getElementById('output').textContent = "Result:\n" + result;
      } catch (e) {
        document.getElementById('output').textContent = "Error:\n" + e;
      }
    }

Christopher Allen

unread,
Jun 24, 2025, 2:11:41 PM6/24/25
to blo...@googlegroups.com
Hi Amber,

Hello! I'm new to Blockly and am a beginner programmer. I'm currently trying to edit the value of a variable block within the Javascript generator.

I am certain I understand what you mean by "edit the value of a variable block within the Javascript generator"—normally generators do not modify blocks, only emit strings of code based on those blocks—but looking at your code I think you must mean that you wish the generated code to contain instructions to set the value of a variable.

BLOCK DEFINITION 
const key_assignment = {
init: function() {
this.appendDummyInput()
.appendField("private key var")
.appendField(new Blockly.FieldVariable("prvKey"), "PRV");
this.appendDummyInput()
        .appendField("public key var")
        .appendField(new Blockly.FieldVariable("pubKey"), "PUB");
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setOutput(true, "String");
this.setTooltip('Assigns generated RSA keys to private and public key variables');
    this.setHelpUrl('');
    this.setColour(225);
    }
    };
    Blockly.common.defineBlocks({list_to_vars : list_to_vars });

This block definition looks good except that it has both previous/next connections and an output connection.  That's not a supported combination: blocks are normally expected to be either a statement block (with next/prev) or a value block (with an output), not both.  In this case, based on the generator I think you intend for it to be a statement block.

JAVASCRIPT GENERATOR
javascript.javascriptGenerator.forBlock['key_assignment'] = function(block) {
const varPrv = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('PRV'), Blockly.Variables.NAME_TYPE); 
  const varPub = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('PUB'), Blockly.Variables.NAME_TYPE);

This is fine but could also be written more succinctly:

      javascript.javascriptGenerator.forBlock['key_assignment'] = function(block, generator) {
const varPrv = generator.getVariableName(block.getFieldValue('PRV'));
   const varPub = generator.getVariableName(block.getFieldValue('PUB'));
 
const code = `
rsaKeypair = KEYUTIL.generateKeypair("RSA", 1024);
${varPrv} = KEYUTIL.getPEM(rsaKeypair.prvKeyObj, "PKCS8PRV");
${varPub} = KEYUTIL.getPEM(rsaKeypair.pubKeyObj);
`;
return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
    };

This looks generally OK, except that:
  1. Because it is returning statements, not a value expression, the last line should just return a string:

    return code;

  2. it is making use of a developer variable (rsaKeypair) that you didn't declare in the block definition.  Unfortunately we don't have good documentation for developer variables—really only this this bit of our API reference—but in short if you want to reference rsaKeypair in your generated code you should add an extra method to the key_assignment block definition to ensure that the variable is properly declared and that no user variable will be allowed to clash with it:

    getDeveloperVariables: function() {
        return ['rsaKeypair'];
    }


    This should result in "var rsaKeypair;" appearing near the top of the generated code.

The function generates a pair of RSA keys. Then, it's supposed to assign the private and public keys to their respective variable blocks in the global Blockly space (these variable blocks are named prvKey and pubKey).

However, after running the code, it simply prints the contents of the private and public keys separately; then, when I try to print the contents of prvKey and pubKey variables, it returns "undefined."

Without more context I can't understand how it could be printing anything, since there are no print statements (e.g. console.log()) in the code generated for this block.

Thus, it seems their values were never actually set, but I thought the lines with ${varPrv} and ${varPub} were updating the values of the variable blocks?

I would expect those lines to update the values of the respective variables (the ones that are by default named prvKey and pubKey).

Is it even possible to update the value of a Blockly variable in the generator code, or am I just going about it the wrong way?

The variable as such (rather than Blockly's representation of it as a FieldVariable backed by a VariableModel) does not actually exist at the time the generator runs, because the actual variable won't come into existence until the generated code is run—but the generated code can absolutely contain both variable declarations and assignment statements.


EXECUTION
    function runCode() {
      try {
        const code = Blockly.JavaScript.workspaceToCode(window.workspace);

If you were to add a console.log(code) statement here it would probably be quite illuminating.
 
        const result = eval(code);
        document.getElementById('output').textContent = "Result:\n" + result;
      } catch (e) {
        document.getElementById('output').textContent = "Error:\n" + e;
      }
    }

Let us know how you get on.  If you have more questions it might be helpful for you to include a screenshot of the workspace as well as a copy of output of workspaceToCode()—as well as any updated block and generator definitions—as unfortunately it is difficult to fully understand the problem you are encountering based solely on your description.


Best wishes,

Christopher

Reply all
Reply to author
Forward
0 new messages