Next block does not have previous statement

179 views
Skip to first unread message

Agrawal

unread,
Jul 5, 2022, 11:44:18 AM7/5/22
to Blockly
Hello All,

I am facing some issues after upgrading my blockly version to latest. I had some workspace data that I have stored in database and now when I am trying to load the data/blocks into workspace then my workspace breaks and got the below error in console - 

Next block does not have previous statement

I am also attaching screenshot of the error for your reference. Please help.


Regards,
Agrawal
Capture-new.PNG

Neil Fraser

unread,
Jul 5, 2022, 12:00:18 PM7/5/22
to blo...@googlegroups.com
Interesting.  Ideally you want to debug this using uncompressed blockly.  Just put a breakpoint on line 944 of xml.js.

However, if you are stuck with compressed Blockly, in the console (or in your code), can you paste this:
TypeError = function(){debugger;}
Then keep the console open and load the XML.  Execution will stop, and you should be able to walk up the call stack one step and determine what 'f.type' is.  That's the block that you are trying to connect to.

My guess is it will be a custom block that has a mutator, but that's just a guess.

--
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/7f64668a-fb7b-4899-8ef5-40e72c1a0aacn%40googlegroups.com.


--

laxmi...@gmail.com

unread,
Jul 5, 2022, 9:32:53 PM7/5/22
to Blockly
Thanks Neil, while Agrawal tries your suggestion, here are more details on it: We have a custom block which changes shape from producing output to statement block depending on a value selection from a dropdown. Here is the sample code that I wrote to produce this error:

Blockly.Blocks['UpgradeTestBlock'] = {
            init: function () {
                const getsetOptions = [['Get', 'Get'], ['Set', 'Set'], ['Remove', 'Remove']];
                var modeMenu = new Blockly.FieldDropdown(getsetOptions, function (value) {
                    var isStatement = value == 'Set' || value == 'Remove';
                    this.getSourceBlock().updateStatement_(isStatement);
                });

                this.appendValueInput('KeyName')
                    .appendField('In Lookup', 'Lookup')
                    .appendField(modeMenu, 'GetOrSet')
                this.setOutput(true);
            },

            updateStatement_: function (newStatement) {
                var oldStatement = !this.outputConnection;
                if (newStatement != oldStatement) {
                    this.unplug(true, true);
                    if (newStatement) {
                        this.setOutput(false);
                        this.setPreviousStatement(true);
                        this.setNextStatement(true);
                    } else {
                        this.setPreviousStatement(false);
                        this.setNextStatement(false);
                        this.setOutput(true);
                    }
                }
            }
        };

Here is the snapshot of the sample block:

Screen Shot 2022-07-05 at 6.30.26 PM.png
If the same block which changes shape is used in a function or a contained stack statement, it gives the error Agrawal mentioned:

TypeError: Next block does not have previous statement.
    at module$contents$Blockly$Xml_domToBlockHeadless (blockly_compressed.js:246:81)
    at module$contents$Blockly$Xml_applyNextTagNodes (blockly_compressed.js:244:423)
    at module$contents$Blockly$Xml_domToBlockHeadless (blockly_compressed.js:246:457)
    at module$contents$Blockly$Xml_applyInputTagNodes (blockly_compressed.js:243:494)
    at module$contents$Blockly$Xml_domToBlockHeadless (blockly_compressed.js:246:395)
    at $.module$exports$Blockly$Xml.domToBlock (blockly_compressed.js:236:280)
    at $.module$exports$Blockly$Xml.domToWorkspace (blockly_compressed.js:231:124)
    at BlocklyComponent.getBlocklyWorkspace (blockly.component.ts:723:13)
    at BlocklyComponent.ngAfterViewInit (blockly.component.ts:680:18)
    at callHook (core.mjs:2577:22)


Thanks,
Lax

Mark Friedman

unread,
Jul 6, 2022, 4:22:47 PM7/6/22
to blo...@googlegroups.com
My guess is that the problem is that you're not saving the state of the block (i.e., via a mutation) so when you de-serialize it in Xml.domToBlockHeadless it is re-created in the wrong state (i.e. with an output).  That is, it was saved in your XML as a statement but is (without any mutation) being created as a value (i.e. with an output).  

There was a change to the code about 18 months ago (in this commit, see line 882) which might explain why it used to work but now doesn't.

-Mark


laxmi...@gmail.com

unread,
Jul 7, 2022, 2:56:33 AM7/7/22
to Blockly
Hi Mark, yes that gave me the clue. Added the mutation functions and now it works fine! 

Appreciate you all! amazing community!

Thanks,
Lax

Reply all
Reply to author
Forward
0 new messages