Why connections are lost when removing all inputs in updateShape_() and reattaching multiple inputs immediately?
Hi everyone,
I’m working with a custom Blockly block that supports multiple mutation types.
Inside the updateShape_() method, I remove all existing inputs and then recreate them dynamically using appendValueInput().
If I reattach one input, its connection is restored correctly.
But when I reattach two or more inputs in sequence, the connections don’t reattach — the blocks become detached.
Here’s a simplified version of what my code looks like:
- updateShape_: function (renderShape = false) {
- // Remove all dynamic inputs
- for (let i = 0; true; i++) {
- let removed = 0;
- const inputs = ['REQUEST', 'RESPONSE'];
- inputs.forEach((name) => {
- try {
- this.removeInput(this.getFullInputName_(name, i));
- removed++;
- } catch (err) {}
- });
- if (removed === 0) break;
- }
- // Recreate inputs
- for (let i = 0; i < this.mutationCount_; i++) {
- this.updateParam_(i, renderShape);
- }
- },
-
-
-
- updateParam_: function (i, renderShape = false) {
- const mutationName = this.getMutationName(i);
- const inputs = this.getMutationInputs(i);
- const fields = this.getMutationFields(i);
- switch (mutationName) {
- case 'sap_call_method_param':
- let input = this.appendValueInput(this.getFullInputName_('VALUE', i))
- .appendField('field')
- .appendField(new window.Blockly.FieldTextInput(fields?.NAME ?? ''), `${this.paramPrefix_}${i}_NAME`)
- .appendField('as')
- .appendField(new window.Blockly.FieldTextInput(fields?.AS ?? ''), `${this.paramPrefix_}${i}_AS`)
- .appendField('type');
- if (renderShape && inputs?.VALUE) {
- input.connection.connect(
- window.Blockly.getMainWorkspace().getBlockById(inputs.VALUE).outputConnection
- );
- }
- break;
- case 'sap_call_method_request':
- let input2 = this.appendValueInput(this.getFullInputName_('REQUEST', i))
- .appendField('TYPE')
- .appendField(new window.Blockly.FieldTextInput(fields?.TYPE ?? ''), `${this.paramPrefix_}${i}_TYPE`)
- .appendField('MODE')
- .appendField(new window.Blockly.FieldTextInput(fields?.MODE ?? ''), `${this.paramPrefix_}${i}_MODE`)
- .appendField('request');
- if (renderShape && inputs?.REQUEST) {
- input2.connection.connect(
- window.Blockly.getMainWorkspace().getBlockById(inputs.REQUEST).outputConnection
- );
- }
- let input3 = this.appendValueInput(this.getFullInputName_('RESPONSE', i))
- .appendField('WHERE')
- .appendField(new window.Blockly.FieldTextInput(fields?.WHERE ?? ''), `${this.paramPrefix_}${i}_WHERE`)
- .appendField('PROTOCOL')
- .appendField(new window.Blockly.FieldTextInput(fields?.PROTOCOL ?? ''), `${this.paramPrefix_}${i}_PROTOCOL`)
- .appendField('response');
- if (renderShape && inputs?.RESPONSE) {
- input3.connection.connect(
- window.Blockly.getMainWorkspace().getBlockById(inputs.RESPONSE).outputConnection
- );
- }
- break;
- }
- }
Problem
-
In the case of sap_call_method_param, the VALUE input reconnects successfully.
-
In the case of sap_call_method_request, neither the REQUEST nor the RESPONSE inputs reconnect.
I confirmed that:
Why do multiple inputs (REQUEST, RESPONSE) fail to reconnect when the block shape is rebuilt, while a single input (VALUE) reconnects just fine?