2

I'm trying to get an object's base type but failing. Chrome's console seems to be able to do it, but I can't.

Here's what the console is giving me:

enter image description here

I'm trying to get Blockly.FieldDropdown somehow.

How is Chrome console able to find it out, but I can't ?

The object is returned by Google Blockly:

var block = Blockly.mainWorkspace.getBlockById(e.blockId);
var field = block.getField(inputId); //field is the object shown in console above...

Or as a standalone working example:

var field = new Blockly.FieldDropdown([['left', 'LEFT'], ['right', 'RIGHT']]);
// these return an empty string, but I'd like to get back "Blockly.FieldDropdown"
console.log(Object.getPrototypeOf(field).constructor.name);
console.log(field.__proto__.constructor.name);
// the following shows "Blockly.FieldDropdown" in front of the properties
// in Chrome's dev console (but not in Firefox for example,
// and the name is not accessible):
// console.log(field);
<script src="https://cdn.jsdelivr.net/npm/blockly@3.20191014.3/blockly.min.js"></script>

I've tried finding a Blockly method that returns the type, but I haven't seen one.

Constantin Groß
  • 10,719
  • 4
  • 24
  • 50
Francis Ducharme
  • 4,848
  • 6
  • 43
  • 81

1 Answers1

0

Here's what I came up with. It works by iterating over the properties of the Blockly object and checking whether the property is instantiable and the object we're checking is a direct instance of it.

This is a very specialised solution that works for a single class and its direct properties. A more general solution would have to recursively iterate over the window (or globalThis if not in browser context) object, which would be very resource-consuming (could freeze the browser) and would have to incorporate a mechanism to prevent Too much recurson errors. Also, with deeper nesting, there could be issues distinguishing instances and sub-instances due to inheritance. This answer gives a lead on that matter.

The reasons why all this is not doable with a trivial built-in solution have been outlined in this related answer.

var field = new Blockly.Field();
var fieldD = new Blockly.FieldDropdown([['left', 'LEFT'], ['right', 'RIGHT']]);
var fieldI = new Blockly.FieldImage('https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png', 1200, 286);

function getBaseType(o) {
  let baseType = null;
  Object.entries(Blockly).find(([name, t]) => {
    let isInstanceOf = t && t.prototype && Object.getPrototypeOf(o) === t.prototype;
    if (isInstanceOf) {
      baseType = `Blockly.${name}`;
    }
    return isInstanceOf;
  });
  return baseType;
}

console.log(getBaseType(field));
console.log(getBaseType(fieldD));
console.log(getBaseType(fieldI));
<script src="https://cdn.jsdelivr.net/npm/blockly@3.20191014.3/blockly.min.js"></script>
Constantin Groß
  • 10,719
  • 4
  • 24
  • 50