'elementDescriptor is undefined' when creating external label for custom element

I can create an external label for custom elements on double click on the element by:

  eventBus.on('element.dblclick', 99999, function(event) {
    var element = event.element;
    if ( /* is my custom element */ && !element.label ) {

      // create external label
      var bounds = { width: 90, height: 14 };
      if ( element.businessObject.name ) {
        bounds = textRenderer.getExternalLabelBounds({}, element.businessObject.name);
      }
      bounds.x = element.x + element.width/2 - bounds.width/2;
      bounds.y = element.y + element.height + 16 - bounds.height/2;

      element.di.label = { bounds };
      element.label = modeling.createLabel(element, bounds, {
          id: element.businessObject.id + '_label',
          businessObject: element.businessObject
        }
      );

      return false;
    }
  });

The external label is generated and I can drag it around as expected. However, when I later try to save the model I receive the following error:

Uncaught (in promise) TypeError: elementDescriptor is undefined
    build webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1231
    parseContainments webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1477
    forEach webpack://bpmn-js-execution-modeler/./node_modules/min-dash/dist/index.esm.js?:185
    parseContainments webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1465
    forEach webpack://bpmn-js-execution-modeler/./node_modules/min-dash/dist/index.esm.js?:185
    parseContainments webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1437
    build webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1252
    parseContainments webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1477
    forEach webpack://bpmn-js-execution-modeler/./node_modules/min-dash/dist/index.esm.js?:185
    parseContainments webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1465
    forEach webpack://bpmn-js-execution-modeler/./node_modules/min-dash/dist/index.esm.js?:185
    parseContainments webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1437
    build webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1252
    parseContainments webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1477
    forEach webpack://bpmn-js-execution-modeler/./node_modules/min-dash/dist/index.esm.js?:185
    parseContainments webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1465
    forEach webpack://bpmn-js-execution-modeler/./node_modules/min-dash/dist/index.esm.js?:185
    parseContainments webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1437
    build webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1252
    parseContainments webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1477
    forEach webpack://bpmn-js-execution-modeler/./node_modules/min-dash/dist/index.esm.js?:185
    parseContainments webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1465
    forEach webpack://bpmn-js-execution-modeler/./node_modules/min-dash/dist/index.esm.js?:185
    parseContainments webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1437
    build webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1252
    toXML webpack://bpmn-js-execution-modeler/./node_modules/moddle-xml/dist/index.esm.js?:1771
    toXML webpack://bpmn-js-execution-modeler/./node_modules/bpmn-moddle/dist/index.esm.js?:91
    toXML webpack://bpmn-js-execution-modeler/./node_modules/bpmn-moddle/dist/index.esm.js?:89
    saveXML webpack://bpmn-js-execution-modeler/./node_modules/bpmn-js/lib/BaseViewer.js?:372
    saveXML webpack://bpmn-js-execution-modeler/./node_modules/bpmn-js/lib/BaseViewer.js?:359
    wrapForCompatibility webpack://bpmn-js-execution-modeler/./node_modules/bpmn-js/lib/util/CompatibilityUtil.js?:56
    <anonymous> webpack://bpmn-js-execution-modeler/./src/app.js?:133
    EventListener.handleEvent* webpack://bpmn-js-execution-modeler/./src/app.js?:132
    js http://localhost:5000/app.js:118
    __webpack_require__ http://localhost:5000/app.js:5492
    <anonymous> http://localhost:5000/app.js:5568
    <anonymous> http://localhost:5000/app.js:5570
app.js line 5317 > eval:1231:19

The problem appears when attempting to serialize the model:

ElementSerializer.prototype.build = function(element) {
  this.element = element;

  var elementDescriptor = element.$descriptor,
      propertyDescriptor = this.propertyDescriptor;

  var otherAttrs,
      properties;

  var isGeneric = elementDescriptor.isGeneric;
  // ...

as element.$descriptor is undefined and used without prior validation.

When I create an external label as posted here I do not have this problem.

How can I make sure that the element descriptor is set properly?

Without seeing the rest of your custom code it’s hard to understand how this is supposed to work.

What is element.di?

This doesn’t look right.

Thanks a lot for your help!

Indeed, the element.label = part wasn’t working properly and after removing it, the error disappeared.

However, in case the property panel is used to create a name (when there is no external label), it appears that an internal label is created implicitly, resulting in an error. I fixed this by replacing element.di.label = { bounds }; by

 if ( element.di && element.di.label ) delete element.di.label;

P.S. I cannot really explain what element.di is, because it is created automatically (not by my extension). I assume it refers to the positioning of elements in the diagram.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.