blockly react.js, running blocks and generator code

916 views
Skip to first unread message

Maya Jaffe

unread,
Oct 7, 2019, 1:40:27 PM10/7/19
to Blockly
Thank you so much for putting together the wonderful resource: https://github.com/google/blockly-samples/tree/master/blockly-react

The sample illustrates how to add custom block code and a toolbox but since I'm very new to react.js I was hoping someone could explicitly point to where and how would one implement the generator code for 'test_react_field' (within blocks/customblocks.js)?

Thanks!

Amber B

unread,
Oct 7, 2019, 2:02:31 PM10/7/19
to Blockly
(Hrm, I really need to review this example in more depth... we're using Blockly in a React environment, but we've been using a fork of https://github.com/patientslikeme/react-blockly-component and I have no idea how similar or different it is to this new example.)

But I need to ask a few more in depth questions here... do you mean where would you run stuff like workspaceToCode, or where would you include the generator code specifically for Blockly[yourGenerator].test_react_field, or?

Maya Jaffe

unread,
Oct 7, 2019, 3:11:53 PM10/7/19
to blo...@googlegroups.com
ooh! I'll look into that repo - thanks! 

As for clarifications: both, please! I was hoping to be pointed to where to put Blockly.Javascript['test_react_field']. (In my vanilla JS webpage I just required a file with my generator scripts within the index.html) as well as the react/component version of Blockly.JavaScript.workspaceToCode(MyWorkspace). Maybe the repo you linked will have more insight. 

The example in my prior email just has a block workspace --- and I think it would be valuable to have a resource like https://blockly-demo.appspot.com/static/demos/generator/index.html which walks through adding generator code and how to eval the blocks.

Thanks again!

On Mon, Oct 7, 2019 at 2:02 PM Amber B <abla...@citizendeveloper.com> wrote:
(Hrm, I really need to review this example in more depth... we're using Blockly in a React environment, but we've been using a fork of https://github.com/patientslikeme/react-blockly-component and I have no idea how similar or different it is to this new example.)

But I need to ask a few more in depth questions here... do you mean where would you run stuff like workspaceToCode, or where would you include the generator code specifically for Blockly[yourGenerator].test_react_field, or?

--
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/23d1667c-248b-4df0-95b1-9008f74e7e75%40googlegroups.com.

Amber B

unread,
Oct 7, 2019, 4:01:53 PM10/7/19
to Blockly
Re: how to import it: hrm, that's an interesting question, actually. We've just been using a CDN to deliver our Blockly stuff without having switched over to the new npm release... My thought would be to have some type of BlocklyExtended class file where you import Blockly, add the definitions for your generator on, then export it. Then you can import that file itself as Blockly wherever else you use it.

As for where to run the generator code, it depends on when and where you need the code. We previously generated our code any time the Blockly workspace changed by adding a listener to the workspace change event, but we ran into performance issue there. Since we tend to have very large workspaces and only really need to generate our code when we save our workspaces to the database or click the button to test the code, we generate our code at that time. (We actually don't have the original Blockly workspace object when doing this... we have our XML saved and then just generate a headless workspace from that XML, which is what we convert to JS.) However, if you're doing a live code preview scenario, you may want to generate your code whenever the workspace changes.

Sam El-Husseini

unread,
Oct 7, 2019, 4:19:22 PM10/7/19
to Blockly
Hey Maya, 

Blockly isn't opinionated about where you define your blocks and their respective generator methods.
As you've pointed out, the test block in the sample was defined in customblocks.js by using the JS definition of blocks in Blockly.
In order to implement the generator for the custom block, set a block generator function to a property on the generator object with the same name as the block type like so:
Blockly.JavaScript['test_react_field'] = function(block) {
   
...
};
The above assumes you're using the JavaScript generator, you can substitute JavaScript with your generator of choice. 
It can be added anywhere in your codebase as long as it's imported by your app, and loaded before you run workspaceToCode.

Since you asked for somewhere specific to add it, try adding the above in customblocks.js.
If you'd like to separate where your blocks are defined and where the generator code sits, you can create another file (say generator.js) and import it in App.js.

Be sure to import the generator module (JavaScript / Python / Lua ...) in whichever file you add your generator code to.
I've updated the react sample to show how to do this. see https://github.com/google/blockly-samples/pull/8

Cheers,
Sam

On Monday, October 7, 2019 at 12:11:53 PM UTC-7, Maya Jaffe wrote:
ooh! I'll look into that repo - thanks! 

As for clarifications: both, please! I was hoping to be pointed to where to put Blockly.Javascript['test_react_field']. (In my vanilla JS webpage I just required a file with my generator scripts within the index.html) as well as the react/component version of Blockly.JavaScript.workspaceToCode(MyWorkspace). Maybe the repo you linked will have more insight. 

The example in my prior email just has a block workspace --- and I think it would be valuable to have a resource like https://blockly-demo.appspot.com/static/demos/generator/index.html which walks through adding generator code and how to eval the blocks.

Thanks again!

On Mon, Oct 7, 2019 at 2:02 PM Amber B <ablaylock@citizendeveloper.com> wrote:
(Hrm, I really need to review this example in more depth... we're using Blockly in a React environment, but we've been using a fork of https://github.com/patientslikeme/react-blockly-component and I have no idea how similar or different it is to this new example.)

But I need to ask a few more in depth questions here... do you mean where would you run stuff like workspaceToCode, or where would you include the generator code specifically for Blockly[yourGenerator].test_react_field, or?

--
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+unsubscribe@googlegroups.com.

Maya Jaffe

unread,
Oct 9, 2019, 9:57:46 PM10/9/19
to blo...@googlegroups.com

Maya Jaffe <jaffe...@gmail.com>

Tue, Oct 8, 5:01 PM (1 day ago)
to sam
Hi Sam,

Thanks SO much for your response to my question and adding the code generator and button to the blockly-react example. I cloned the updated repo but I have some follow up questions I was hoping you could answer:

1. I'm now getting the error "TypeError: Cannot read property 'register' of undefined" when I try to npm start build , but was able to build the example prior to the generator addition. 

2.  I was wondering if this may be due to the fat arrow function assignment for generateCode, and if not I'm curious why/how that works in react.js?

3. I'm very new to react.js and couldn't seem to find where App is being instantiated (not in index.html) would you mind pointing me to the reactDOM.render? 

4. I was hoping you could provide some clarification of my mental model for ref={e => this.simpleWorkspace = e}  I read that this modifies a child without using props but I'm still a little fuzzy with how this works. Are we using the ref to define the workspace then we can pass that workspace to generate code? 

Thanks so much for this invaluable resource! 

On Mon, Oct 7, 2019 at 4:19 PM 'Sam El-Husseini' via Blockly <blo...@googlegroups.com> wrote:
Hey Maya, 

Blockly isn't opinionated about where you define your blocks and their respective generator methods.
As you've pointed out, the test block in the sample was defined in customblocks.js by using the JS definition of blocks in Blockly.
In order to implement the generator for the custom block, set a block generator function to a property on the generator object with the same name as the block type like so:
Blockly.JavaScript['test_react_field'] = function(block) {
   
...
};
The above assumes you're using the JavaScript generator, you can substitute JavaScript with your generator of choice. 
It can be added anywhere in your codebase as long as it's imported by your app, and loaded before you run workspaceToCode.

Since you asked for somewhere specific to add it, try adding the above in customblocks.js.
If you'd like to separate where your blocks are defined and where the generator code sits, you can create another file (say generator.js) and import it in App.js.

Be sure to import the generator module (JavaScript / Python / Lua ...) in whichever file you add your generator code to.
I've updated the react sample to show how to do this. see https://github.com/google/blockly-samples/pull/8

Cheers,
Sam

On Monday, October 7, 2019 at 12:11:53 PM UTC-7, Maya Jaffe wrote:
ooh! I'll look into that repo - thanks! 

As for clarifications: both, please! I was hoping to be pointed to where to put Blockly.Javascript['test_react_field']. (In my vanilla JS webpage I just required a file with my generator scripts within the index.html) as well as the react/component version of Blockly.JavaScript.workspaceToCode(MyWorkspace). Maybe the repo you linked will have more insight. 

The example in my prior email just has a block workspace --- and I think it would be valuable to have a resource like https://blockly-demo.appspot.com/static/demos/generator/index.html which walks through adding generator code and how to eval the blocks.

Thanks again!

On Mon, Oct 7, 2019 at 2:02 PM Amber B <abla...@citizendeveloper.com> wrote:
(Hrm, I really need to review this example in more depth... we're using Blockly in a React environment, but we've been using a fork of https://github.com/patientslikeme/react-blockly-component and I have no idea how similar or different it is to this new example.)

But I need to ask a few more in depth questions here... do you mean where would you run stuff like workspaceToCode, or where would you include the generator code specifically for Blockly[yourGenerator].test_react_field, or?

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

--
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/f39989db-f7c0-43db-9aab-40cd2fd8aa85%40googlegroups.com.

Coda Highland

unread,
Oct 9, 2019, 11:23:35 PM10/9/19
to blo...@googlegroups.com
I can't answer too much about the Blockly-specific stuff here, but I know React. You say you're new, so I'm going to explain more than I might technically need to; please forgive me if I explain anything you already know. :)

The fat arrow syntax you see there works just fine with React. As is always the case, it just binds `this`. That's technically a field initializer, not a method; field initializers are run during object construction, so a new function binding is created every time a new instance is created, and React doesn't change that. So that means that each <App> component has its own `generateCode` function.

The reason for using the fat arrow syntax in React is so that you can pass around methods in properties. If you didn't use =>, then `this` would refer not to the component that owns the method, but to the props object of the component you passed the property into. (You could work around this in other ways, but it's kinda messy and can easily waste a lot of resources if you're not careful. This particular pattern is both easy to read and just about as efficient as possible.)

As for the `ref` property: When you pass a function into a `ref` property, it gets invoked after the component is constructed, when React inserts the component into its parent's internal DOM. The callback is invoked with one parameter, which is the Javascript object representing the newly-constructed child component. The typical pattern for this is what you see in this code -- you use an arrow function (so that `this` is bound appropriately) to store a reference to the new component somewhere you can access it.

You really shouldn't think of it as allowing you to modify a child without using props. It's messier than that and you really shouldn't modify the child directly that way because React won't be able to keep track of what you've done. (The typical pattern is to expose methods on the component that then uses React's state functionality to update React's internal data store.) But in this particular case, we're instead using it as an escape route to get out of the React paradigm and gain access to non-React objects. From this perspective, your guess is pretty close -- we're using the `ref` function to grab a reference to the workspace so that we can make use of it directly, which of course includes passing it to the generator.

BTW, the ReactDOM.render call is in src/index.js.

/s/ Adam

Sam El-Husseini

unread,
Oct 9, 2019, 11:40:16 PM10/9/19
to Blockly
Hey Maya,

In regards to 1. That's a bug. fieldRegistry is a new API in the upcoming release. That was my bad.
The release should be coming up next week, but in the meantime, you can replace: 
Blockly.fieldRegistry.register(...)
with
Blockly.Field.register(...)
in BlocklyReactField.jsx

Adam, thank you for responding to the other parts of the question.

Cheers,
Sam
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+unsubscribe@googlegroups.com.

--
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+unsubscribe@googlegroups.com.

--
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+unsubscribe@googlegroups.com.

Maya Jaffe

unread,
Oct 10, 2019, 5:26:15 AM10/10/19
to blo...@googlegroups.com
Thank you both for the clarification!

Cheers,
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.

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

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

--
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/74ca5a91-5deb-4c25-a250-6857455a5cf6%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages