Get Code generated variable names

128 views
Skip to first unread message

C Ben

unread,
Apr 21, 2021, 9:45:39 AM4/21/21
to Blockly
Hello,
All my blockly programs generates a JavaScript with variable declarations in the begining.
For example :

var number1, number2, r_C3_A9ponses;

afterwards, variables are used and defined with value.

Because Blockly is smart ;) it generates unique identifier names or transform utf-8 into "simpler" strings. Here the variable defined as "réponse" in Blockly UI and its corresponding variable name generated by generator is : "r_C3_A9ponses"

I'd like to retrieve variable values in my tool but when I use  myWorkspace.getAllVariables(myWorspace), I get the name of variables chosen in Blockly UI not the generated ones. Is there any means to retrieve the generated name instead of Blockly UI names ?
Thanks for your help,

Chris

Beka Westberg

unread,
Apr 21, 2021, 9:07:04 PM4/21/21
to blo...@googlegroups.com
Hello,

I think you can do this by passing the ids of all of the variables to the variableDB_ on the generator.

So it would be something like:
```
// I might have some of the exact names wrong, but that's the basic idea.
var varNames = myWorkspace.getAllVariables().map((varModel) => Blockly.JavaScript.variableDB_.getName(varModel.getId()));
```

If you can look here, passing the variable ID is how the names are created within the block-code generators =)

I hope that helps! If you have any further questions please reply!
--Beka

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/blockly/3bdc99c5-5450-4195-b92e-7f93e80b2424n%40googlegroups.com.

C Ben

unread,
Apr 22, 2021, 2:57:59 PM4/22/21
to Blockly
Hello Beka,
Thanks for your answer. Unfortunately, it doesn't work as I expected.
I've implemented your suggestion within my method as follows :

function getBlocklyVariables() {
workspace.getAllVariables(workspace)
.map((varModel) => {
return {
name: varModel.name, // I get "bonnes réponses" : which corresponds to name chosen in Blockly UI
id: varModel.getId(), // I get "Qxkfm._U!%3Z:CfF.q_M"
realName : Blockly.JavaScript.variableDB_.getName(varModel.getId()) // I get "Qxkfm__U__253Z_CfF_q_M"
};
});

The realName I would have expected is "bonnes_r_C3_A9ponses" which corresponds to the generated var name generated by Blockly's JS generator with workspaceToCode() function.

Thanks again for your help,
Chris

Beka Westberg

unread,
Apr 22, 2021, 7:09:56 PM4/22/21
to blo...@googlegroups.com
Ah sorry! It seems like there's special behavior for variables, so you have to make sure to pass Blockly.VARIABLE_CATEGORY_NAME to the getName() function as well.

So I think your code would need to look like:
```
function getBlocklyVariables() {
workspace.getAllVariables(workspace)
  .map((varModel) => {
    return {
      name: varModel.name,
      id: varModel.getId(),
      realName : Blockly.JavaScript.variableDB_.getName(varModel.getId(), Blockly.VARIABLE_CATEGORY_NAME)
    };
  }
);
```

I hope that helps!
--Beka

C Ben

unread,
Apr 23, 2021, 5:32:07 AM4/23/21
to Blockly
Thanks Beka, unfortunately the Blockly.JavaScript.variableDB_.getName(varModel.getId(), Blockly.VARIABLE_CATEGORY_NAME) returns exactly the same value than Blockly.JavaScript.variableDB_.getName(varModel.getId()) 
For info, the new call with the "VARIABLE_CATEGORY_NAME"  parameter raises a message :
"Deprecated call to Blockly.Names.prototype.getName without defining a variable map. To fix, add the following code in your generator's init() function: Blockly.YourGeneratorName.variableDB_.setVariableMap(workspace.getVariableMap());"

Tougher than I thought... I could also split the generated JS code first line (the one with the var ... declarations), and split it to obtain name vars but I would definitely prefer to find a more sustainable and elegant way :-)


Thanks
Chris

C Ben

unread,
Apr 23, 2021, 12:31:53 PM4/23/21
to Blockly
I update my last message. In fact, I've followed the advice given by the console message so I've added before my last code :
Blockly.JavaScript.variableDB_.setVariableMap(
workspace.getVariableMap()
);

and it works, I finally get the safe variable names used in the generator code.
Thanks,
Chris

Beka Westberg

unread,
Apr 23, 2021, 4:29:53 PM4/23/21
to blo...@googlegroups.com
Yay I'm glad it's finally working! I hope the rest of your project goes smoothly from here hehe. But if you ever have more questions we're happy to help :D

Also I never asked, but I'm curious. What are you trying to get the generated names for? Is it for showing a code preview? Or something else?

Best wishes,
--Beka

C Ben

unread,
Apr 26, 2021, 4:04:49 AM4/26/21
to Blockly
Hello Beka,
It's secret defense but I share it anyway ;-) I try to implement a step by step debugger and show the blockly user defined variables values in live. Associated to the highlight function you can see internal values being allocated progressively.

Best wishes,

Chris

Beka Westberg

unread,
Apr 26, 2021, 5:58:08 PM4/26/21
to blo...@googlegroups.com
Oh that sounds so awesome! I know debugging is a bit of a hot topic at the moment so it's really cool to hear from someone who's working on it :D If there are any API hooks you need to make building this easier, be sure to post an issue on the core repo. I'm sure those are things the core team definitely wants to add =)

Thanks once again for sharing, that's really interesting! I hope your work on it goes well.

Best wishes,
--Beka

Johnny Oshika

unread,
May 2, 2021, 1:06:10 AM5/2/21
to Blockly
I was able to get the generated variable names by passing in the user specified variable name to Blockly.JavaScript.variableDB_.getName() instead of the variable id. So the complete code is:

Blockly.mainWorkspace
  .getAllVariables()
  .map(varModel =>  
      ({
           userVariable: varModel.name,
           blocklyVariable:
               Blockly.JavaScript.variableDB_.getName(
                    varModel.name,
                    Blockly.JavaScript.VARIABLE_CATEGORY_NAME
               )
       })
   )

That will output something like this:

[
    {
        "userVariable": "a long variable name",
        "blocklyVariable": "a_long_variable_name"
    },
    {
        "userVariable": "name",
        "blocklyVariable": "name2"
    }
]

I'm a little stumped that this works, however. Looking at the source code that Beka linked to (https://github.com/google/blockly/blob/3fe56b083c62549cb2bdb17270846bf17ced5d7a/generators/javascript/variables.js#L20), I would think that the variable ID should be passed in and not the name. However, the opposite seems to work for me.

Johnny Oshika

unread,
May 2, 2021, 1:18:37 AM5/2/21
to Blockly
Interestingly, I get the deprecation message that Chris got when I use Blockly.VARIABLE_CATEGORY_NAME instead of  Blockly.JavaScript.VARIABLE_CATEGORY_NAME.

The following works, but results in a deprecation message:

Blockly.mainWorkspace
  .getAllVariables()
  .map(varModel =>  
      ({
           userVariable: varModel.name,
           blocklyVariable:
               Blockly.JavaScript.variableDB_.getName(
                    varModel.name,
                    Blockly.VARIABLE_CATEGORY_NAME
               )
       })
   )

The following also works, but without a deprecation message:

Blockly.mainWorkspace
  .getAllVariables()
  .map(varModel =>  
      ({
           userVariable: varModel.name,
           blocklyVariable:
               Blockly.JavaScript.variableDB_.getName(
                    varModel.name,
                    Blockly.JavaScript.VARIABLE_CATEGORY_NAME
               )
       })
   )

Excluding VARIABLE_CATEGORY_NAME altogether results in the same output as including Blockly.JavaScript.VARIABLE_CATEGORY_NAME (i.e. no deprecation message):

Blockly.mainWorkspace
  .getAllVariables()
  .map(varModel =>  
      ({
           userVariable: varModel.name,
           blocklyVariable:
               Blockly.JavaScript.variableDB_.getName(
                    varModel.name
               )
       })
   )

Johnny Oshika

unread,
May 2, 2021, 2:15:08 AM5/2/21
to Blockly
Well I stand to be corrected. Everything I wrote before was when I had the Blockly dev tools loaded (using createPlayground from @blockly/dev-tools). Dev tools seems to change the behaviour of  Blockly.JavaScript.variableDB_.getName(). Without dev tools, I do need to pass the variable ID to getName(). This is what's working for me now:

Blockly.JavaScript.init(ws); // To initialize Blockly.JavaScript.variableDB_ (https://github.com/google/blockly/issues/4060#issuecomment-662602322)

workspace.getAllVariables().map(varModel => ({
  userVariable: varModel.name,
  blocklyVariable: Blockly.JavaScript.variableDB_.getName(
    varModel.getId(),
    Blockly.VARIABLE_CATEGORY_NAME,
  ),
})),


Beka Westberg

unread,
May 2, 2021, 9:24:06 PM5/2/21
to blo...@googlegroups.com
Huh that's weird! I wonder if it has to do with how workspaceToCode is getting called. Maybe Blockly.JavaScript isn't getting initialized?

Anyway, thank you for posting! I'll be sure to point people to this thread if they run into similar issues =)

--Beka

Johnny Oshika

unread,
May 11, 2021, 11:10:52 AM5/11/21
to Blockly
I'm not really sure why I was seeing the discrepancy. I was testing using Blockly Playground (i.e. createPlayground from '@blockly/dev-tools') in a custom React app, so maybe this contributed to the discrepancy? Once I switched to running my code in my production application using headless Blockly, the behaviour became consistent with Chris'.

Thx,
Johnny

Reply all
Reply to author
Forward
0 new messages