I’m encountering a bug in App Inventor where procedure blocks added to the backpack don’t display their custom names in the flyout. Here’s the sequence of events:
- I create a procedure block in the workspace and rename it from “procedure” which is the default name, to custom name “myBlock.”
- I add this renamed block to the backpack using the right-click menu.
- When I open the backpack and check the flyout, the block appears as “procedure” instead of “myBlock.”
The custom name (“myBlock”) is correctly stored in the block’s XML, as shown in the logs below, but the flyout still displays the default “procedure” name. This mismatch is confusing and disrupts my workflow.
Log When Adding to Backpack
Here’s the XML of the block when it’s added to the backpack:
<block type="procedures_defnoreturn" id="#4qif]FYIDIaBg$I~}%c" ...><field name="NAME">myBlock</field></block>
This confirms that the backpack stores the custom name correctly in the <field name="NAME"> tag.
Log When Opening the Backpack
When I open the backpack, the following logs are generated:
aiblockly-0.nocache.js:67146 Backpack contents: <xml><block xmlns="https://developers.google.com/blockly/xml" type="procedures_defnoreturn" id="#4qif]FYIDIaBg$I~}%c" x="-559.40625" y="-1050.87890625"><field name="NAME">myBlock</field></block></xml>
(anonymous) @ aiblockly-0.nocache.js:67146
Promise.then
AI.Blockly.Backpack.openBackpack @ aiblockly-0.nocache.js:67145
e @ aiblockly-0.nocache.js:3948
aiblockly-0.nocache.js:67148 Backpack contents length: 1
(anonymous) @ aiblockly-0.nocache.js:67148
Promise.then
AI.Blockly.Backpack.openBackpack @ aiblockly-0.nocache.js:67145
e @ aiblockly-0.nocache.js:3948
aiblockly-0.nocache.js:67153 Backpack block type: undefined id: #4qif]FYIDIaBg$I~}%c newBackpack: [object Element]
(anonymous) @ aiblockly-0.nocache.js:67153
Promise.then
AI.Blockly.Backpack.openBackpack @ aiblockly-0.nocache.js:67145
e @ aiblockly-0.nocache.js:3948
aiblockly-0.nocache.js:67155 Backpack contents: [object Element]
These logs indicate that the XML is retrieved with the correct name (“myBlock”), but the flyout receives an unprocessed [object Element] instead of a fully initialized block. This seems to cause the default “procedure” name to be displayed instead.
What I’ve Tried
I’ve dug into this issue and here’s what I’ve discovered:
-
Verified Storage:
The XML logged when adding the block to the backpack includes “myBlock” in the <field name="NAME"> tag, so the custom name is being stored correctly.
-
Inspected Display Logic:
When opening the backpack, the logs show the block type as undefined and the content as [object Element]. This suggests the flyout is receiving raw XML rather than a processed Blockly block object.
-
Code Analysis:
- The
addToBackpack function serializes the block into XML with the custom name, which works as expected.
- The
openBackpack function retrieves the XML but passes it directly to the flyout’s show method without converting it into a proper block object.
- I suspect the flyout requires fully initialized blocks (not raw XML) to display the correct name.
Based on this, I’ve proposed a potential fix by modifying the openBackpack function to convert the XML into Blockly blocks using Blockly.Xml.domToBlock. Here’s my suggested code:
AI.Blockly.Backpack.prototype.openBackpack = function(e) {
if (e) {
e.stopPropagation();
if (e.button === 2) {
this.flyout_.hide();
this.openBackpackMenu(e);
return;
}
}
if (!this.isAdded && this.flyout_.isVisible()) {
this.flyout_.hide();
} else {
this.getContents().then((contents) => {
console.warn('Backpack contents: ' + contents);
const len = contents.length;
console.warn('Backpack contents length: ' + len);
const newBackpack = [];
for (let i = 0; i < len; i++) {
newBackpack[i] = Blockly.Versioning.upgradeComponentMethods(Blockly.utils.xml.textToDom(contents[i]).firstChild);
console.warn('Backpack block type: ' + newBackpack[i].type + ' id: ' + newBackpack[i].id + ' newBackpack: ' + newBackpack[i]);
}
console.warn('Backpack contents: ' + newBackpack);
Blockly.hideChaff();
this.flyout_.show(newBackpack);
});
}
};
This approach should turn the XML into initialized blocks, allowing the flyout to display “myBlock” instead of “procedure.” However, I haven’t tested this fully, and I’m unsure if it aligns with App Inventor’s specific implementation.
Question
The issue still persists despite my investigations, and I’m seeking guidance to resolve it. I’d like help with the following:
- Is
Blockly.Xml.domToBlock the right method to convert the XML into blocks for the flyout to display the custom name correctly?
- Are there other parts of the App Inventor or Blockly codebase that might influence how procedure blocks are rendered in the backpack flyout?
- Can someone with experience in App Inventor or Blockly confirm if my proposed fix is heading in the right direction, or suggest a better way to solve this?
I’d greatly appreciate any advice or solutions to fix this naming issue. Thanks for your help!