Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Extending fields for first time / struggling

35 views
Skip to first unread message

Chris Rowan

unread,
Nov 22, 2024, 12:05:07 PM11/22/24
to Blockly
Blockly noob trying to extend a field so I can populate it with values from an API call.

Have read the docs but getting a puzzling error.


mappingService.js:585
Error loading workspace: TypeError: Blockly.FieldSearchDropdown is not a constructor at BlockSvg$$module$build$src$core$block_svg.init (blocks.js:9:26) at BlockSvg$$module$build$src$core$block_svg.doInit_ (javascript.ts:32:14) at new BlockSvg$$module$build$src$core$block_svg (javascript.ts:32:14) at WorkspaceSvg$$module$build$src$core$workspace_svg.newBlock (javascript.ts:32:14) at appendPrivate$$module$build$src$core$serialization$blocks (math.ts:415:5) at appendInternal$$module$build$src$core$serialization$blocks (math.ts:415:5) at append$$module$build$src$core$serialization$blocks (math.ts:415:5) at BlockSerializer$$module$build$src$core$serialization$blocks.load (javascript.ts:32:14) at Object.load$$module$build$src$core$serialization$workspaces [as load] (javascript.ts:32:14) at Object.showComplexMappingEditor (mappingService.js:577:50)


showComplexMappingEditor

@

mappingService.js:585


(anonymous)

@

mappingService.js:336

Initial code to extend

class FieldSearchDropdown extends Blockly.FieldDropdown {
    constructor(options, validator) {
        super(options, validator);
        this.sourceData = options.sourceData || [];
    }

    showEditor_() {
        super.showEditor_();
        const input = this.htmlInput_;
        input.addEventListener('input', this.onInputChange_.bind(this));
    }

    onInputChange_(event) {
        const input = event.target.value.toLowerCase();
        const filteredOptions = this.sourceData.filter(option =>
            option[0].toLowerCase().includes(input)
        );
        this.menuGenerator_ = filteredOptions;
        this.dropdownCreate_();
    }
}

// Register the custom field
if (!Blockly.registry.hasItem(Blockly.registry.Type.FIELD, 'field_search_dropdown')) {
    Blockly.registry.register(Blockly.registry.Type.FIELD, 'field_search_dropdown', FieldSearchDropdown);
}

export { FieldSearchDropdown };

Loading Blockly as per below 

<!DOCTYPE html>
<html>
<head>

    <!-- Load your scripts as modules -->
    <script type="module" src="./js/customFields.js"></script>
    <script type="module" src="./js/blocks.js"></script>
    <script type="module" src="./js/mapper.js"></script>
    <script type="module" src="./js/state.js"></script>
    <script type="module" src="./js/modals.js"></script>
    <script type="module" src="./js/mappingService.js"></script>

TIA for any suggestions



Chris Rowan

unread,
Nov 22, 2024, 2:11:09 PM11/22/24
to Blockly
Please disregard. Still learning my way around. A good night's sleep and the answer was obvious.

class FieldSearchDropdown extends Blockly.FieldDropdown --> class Blockly.FieldSearchDropdown extends Blockly.FieldDropdown

Christopher Allen

unread,
Nov 26, 2024, 10:56:43 AM11/26/24
to blo...@googlegroups.com
Hi Chris,

I am glad you were able to solve your own problem—that is the most important thing!—but you have piqued my curiosity, because there's nothing obviously wrong with your original code that would explain the error message you quoted—whereas the line you mentioned in your follow-up as the solution:

 class Blockly.FieldSearchDropdown extends Blockly.FieldDropdown

… is not syntactically valid JavaScript, and should have generated an error along the lines of:

SyntaxError: Unexpected token '.'

I would love to know more about exactly what is going on here, if you can fill in whatever bits of the puzzle I am missing.


Sincerely, an engineer who is fortunately not a cat,

Christopher

Chris Rowan

unread,
Nov 26, 2024, 2:15:53 PM11/26/24
to blo...@googlegroups.com
I typed it in and left part out. Very sorry. Here's the correct code:

Blockly.FieldSearchDropdown = class extends Blockly.FieldDropdown {

--
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 visit https://groups.google.com/d/msgid/blockly/CAN0w5eaaSokyqoaYw4wifDtF3jT2iXme9fzH6E%2B72xOFMyP5Tw%40mail.gmail.com.

Christopher Allen

unread,
Nov 27, 2024, 8:26:48 AM11/27/24
to blo...@googlegroups.com

I typed it in and left part out. Very sorry. Here's the correct code:

Blockly.FieldSearchDropdown = class extends Blockly.FieldDropdown {


Ahh that makes sense—but beware: normally a module namespace object (e.g. the Blockly object that results from the statement import * as Blockly from 'blockly') is effectively immutable and cannot have additional properties (like .FieldSearchDropdown) added to it in this way.  It only works at all because of quirks in how we package and ship Blockly, and how you build your app.  Consequently, I would strongly recommend against doing this as it will probably break in some future version of Blockly and/or your build system.

Reply all
Reply to author
Forward
0 new messages