Set a default timerEventDefinition after creating a boundary event

I’m trying to apply a default value to the timerEventDefinition when creating a timer boundary event. I have tried the following approach, but unfortunately this gives me an error. Is there a way to make this work?

  const eventBus = bpmnModeler.get('eventBus')
  eventBus.on('commandStack.shape.create.postExecute', function(event) {
	var modeling = bpmnModeler.get('modeling')
	var element = event.context.shape
	console.log('Added: ' + element.type)

	if (element.type == 'bpmn:BoundaryEvent') {
	  var boundaryEvent = element.businessObject
	  if ('eventDefinitions' in boundaryEvent) {
		var eventDefinition = boundaryEvent.eventDefinitions[0]
		if (eventDefinition.$type == 'bpmn:TimerEventDefinition') {
		  modeling.updateProperties(eventDefinition, {
			'timeDuration': 'P2D'
		  })
		}
	  }
	}
  })

The error I get:
UpdatePropertiesHandler.js:171 Uncaught TypeError: Cannot read property 'get' of undefined

Hi Rick,

timeDurations are stored as bpmn:FormalExpression in the bpmn.

    <bpmn:boundaryEvent id="Event_0kbxgp5" attachedToRef="Activity_1tay8vr">
      <bpmn:timerEventDefinition id="TimerEventDefinition_0bo9rh7">
        <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">P2D</bpmn:timeDuration>
      </bpmn:timerEventDefinition>
    </bpmn:boundaryEvent>

Therefore you need to create such a FormalExpression first and set your desired value:

[...]
  const bpmnFactory = bpmnJS.get("bpmnFactory");

  const formalExpression = bpmnFactory.create("bpmn:FormalExpression", {
    body: "PT5M"
  });
  formalExpression.$parent = eventDefinition;

  eventDefinition.set("timeDuration", formalExpression);
[...]

Also see this thread.

Regards
Max

1 Like

Thanks! That works!

Just for my understanding, why can’t I use modeling.updateProperties on the eventDefinition?

The timeDuration is not a property of the eventDefinition you created. updateProperies is to be used for direct properties of the respective element (example: <bpmn2:startEvent id="StartEvent_1" name="Foo">. Here the name is a property of the startEvent).

But I’m also not able to set any other properties, like name or id on the eventDefinition, while I was able to set undefined, randomly named properties on a ServiceTask with updateProperties.

while I was able to set undefined, randomly named properties on a ServiceTask with updateProperties .

You should also be able to set defined simple properties, such as name, using modeling.updateProperties on all elements which have an underlying BPMN business object - please share an example if not working.

Regarding eventDefinition and the example you posted initially, because of the structure here (see xml snippet in my first reply) we need to traverse on the business object and can therefore not use updateProperties, but you could directly edit. For example this should be working:

[...]
  const bpmnFactory = bpmnJS.get("bpmnFactory");

  const formalExpression = bpmnFactory.create("bpmn:FormalExpression", {
    body: "PT5M"
  });
  formalExpression.$parent = eventDefinition;

  eventDefinition.set("timeDuration", formalExpression);

  eventDefinition.timeDuration.body = "PT6M";
[...]

Notice that this then does not bring you redo/undo functionality (you would need to look into writing your own CommandHandler (you could take a look at https://github.com/bpmn-io/bpmn-js-properties-panel/blob/master/lib/cmd/UpdateBusinessObjectHandler.js)

#updateProperties only works for diagram shapes and connections. Since an event definition is not a diagram shape but part of a diagram shape you can not use #updateProperties.