How can I dynamically generate content of a Blockly dropdown menu? How can I dynamically generate content of a Blockly dropdown menu? flask flask

How can I dynamically generate content of a Blockly dropdown menu?


This is a pretty old question, so I'm not sure if the OP still needs an answer, but I'm answering on the assumption that this is a situation where the OP is using an asynchronous JavaScript call to the backend and can't just return the results because of that.

We have a not dissimilar situation in our application (albeit using a nodejs backend) where we're populating dropdowns based on options retrieved from Google Cloud Datastore. We have a React App, so our solution was to have a Flux store attached to the window which our asynchronous call populates upon completing, and then have the dropdown generation code access that store. Obviously, a full Flux store may not be appropriate for all situations, but my general advice here would be to pass in an option generator function and have it read from a store or other variable on the window, and then have your call to the backend run on page load (or when otherwise appropriate) and populate the store on the window. If your app inits before the call is done, you can have it set up to show that it's loading options based on a flag on the store.

As a very simplified case, you might have:

// on page loadwindow.store = {done: false};myBackendCall().then(function(results){    window.store = {        results: results,        done: true    };}).catch(function(error){    console.error(error);    window.store = {results: [], done: true};});

Then in your selector, you might go with something like:

function generateOptions(){    if(!window.store.done) {        return [['Loading...', 'loading']];    } else {        return [['Select a file', '']].concat(window.store.results);    }}this.appendDummyInput()    .appendField(new Blockly.FieldDropdown(generateOptions), fieldName);

Obviously, this is a gross simplification, but I think it's enough to show the technique. We actually made our own custom Blockly fields for this for other reasons, but this should still work with a vanilla Blockly dropdown. Swap out Promise chaining for callbacks if that's how your setup is. You could also make the call inside the block and set a variable on the block itself (this.store or whatever), but that would result in multiple calls being made for multiple instances of the block, so that may not be appropriate for you.