Proper way to create and update activities in BPMN-JS Modeler

Hello, everybody!

First of all, thank you for this very flexible library.

I have spent a few days so far to understand how to create and update elements in modeler programatically. But still not sure how to do it in proper way.

My cases:

  1. Create service task with predefined connector and some input and output parameters. Now I do the following, but I noticed that $parent properties for all child Moddle elements are undefined.
class MyPalette {


    getPaletteEntries() {
        const startCreate = event => {
            const myServiceTaskBusinessObject = this.moddle.create('bpmn:ServiceTask', {
                id: `MyServiceTask_${}`,
                extensionElements: this.moddle.create('bpmn:ExtensionElements', {
                    values: [
                        this.moddle.create('camunda:Connector', {
                            connectorId: 'MyServiceTaskConnectorId',
                            inputOutput: this.moddle.create('camunda:InputOutput', {
                                inputParameters: [
                                    this.moddle.create('camunda:InputParameter', { name: 'parameter1' }),
                                    this.moddle.create('camunda:InputParameter', { name: 'parameter2' }),
            const serviceTaskShape = this.elementFactory.create('shape', {
                type: 'bpmn:ServiceTask',
                businessObject: myServiceTaskBusinessObject,

            this.create.start(event, serviceTaskShape);

        return {
            'create-my-service-task': {
                group: 'my-activities',
                title: 'Create My Service Task',
                action: {
                    dragstart: startCreate,
                    click: startCreate,

  1. I created my custom properties panel. So I need to update businessObject of my service task. Now I do the following to update input parameter (deep nested property of element).
export function updateInputParameter(element, modeler, parameterName, parameterValue) {
    const moddle = modeler.get('moddle');
    const extensionElementValues = element.businessObject.extensionElements.values;
    const connector = find(propEq('$type', 'camunda:Connector'), extensionElementValues);
    const { inputOutput: { inputParameters } } = connector;
    const parameter: any = find(propEq('name', parameterName), inputParameters);

    if (parameter) {
        parameter.value = parameterValue;
    } else {
        inputParameters.push(moddle.create('camunda:InputParameter', { name: parameterName, value: parameterValue }));

Looks like both approaches work. But maybe there is another (proper) way to do it?

Hey, could you please format your code so that we can understand what’s going on and help you?

I am trying. Looks like something wrong with my format

Check it now, please.

1 Like

Thanks for your code snippet! Can you maybe share a CodeSandbox which we can try out? It will help us to check what’s going on there more in detail.