Skip to content

RunMethod User Guide

This guide is for users who configure runMethod actions through JSON configuration files.

Table of Contents

What is RunMethod?

RunMethod allows you to execute backend metamethods from the UI. Users can:

  • Select objects in tables/trees
  • Optionally fill in a form (editor)
  • Execute a backend method with the selected objects
  • See the results (toast notifications, entity refreshes, etc.)

Basic Configuration

A runMethod action has three main parts:

json
{
  "id": "action-id",
  "method": "runMethod",
  "label": "Button Label",
  "icon": "icon-name",
  "request": {
    "parent": "MetaTypeName",
    "methodName": "backendMethodName",
    "objects": [/* LinkEndpoint strategies */]
  },
  "editor": {/* Optional form configuration */},
  "response": {/* Optional actions after success */}
}

Required Properties

  • request.parent: The metamodel type (e.g., "ProductionOrder")
  • request.methodName: The backend method to call
  • request.objects: Array of LinkEndpoint strategies that determine which objects to pass

Optional Properties

  • editor: Form configuration for user input before execution
  • response: Client-side actions to execute after success

LinkEndpoint Strategies

LinkEndpoints determine which objects are passed to the backend method. You can use 7 different strategies:

Strategy Overview

StrategyWhen to UseExample
objectIdFixed object GUIDConfig object, system settings
getFromItemUser's selected itemsMost common case
getFromCreatedObjectJust-created object⚠️ Not yet supported
getSelectedObjectForEventIdObject from eventNotification clicks
selectPanelUser picks from modalChoose supplier, operator
getSelectedObjectForPanelIdObjects from another panelMulti-panel workflows
getFromActionIdObjects from another actionAction chaining

1. objectId

Use a hardcoded object GUID.

json
{
  "objects": [
    {
      "objectId": {
        "objectGuid": "123e4567-e89b-12d3-a456-426614174000"
      }
    }
  ]
}

When to use: Configuration objects, system settings, or any fixed reference.

2. getFromItem

Use the objects the user has selected in the table/tree.

json
{
  "objects": [
    {
      "getFromItem": true
    }
  ]
}

When to use: This is the most common strategy. Use it when the action operates on user-selected rows/nodes.

User flow:

  1. User selects 1+ items in table/tree
  2. User clicks the action button
  3. Method executes with selected object IDs

3. getFromCreatedObject

⚠️ Not yet supported for runMethod

Intended for chaining: create → link → runMethod.

4. getSelectedObjectForEventId

Get the object that triggered a specific event.

json
{
  "objects": [
    {
      "getSelectedObjectForEventId": "notification--on-click"
    }
  ]
}

When to use: Event-triggered actions like notification clicks, auto-triggers.

5. selectPanel

Open a modal panel for the user to select an object.

json
{
  "objects": [
    {
      "selectPanel": {
        "panel": {
          "id": "supplier-select",
          "type": "table",
          "request": {
            "metaTypeName": "Supplier"
          },
          "columns": [
            {"attribute": "name", "label": "Supplier Name"}
          ]
        }
      }
    }
  ]
}

When to use: When the target object is not predetermined (e.g., "Assign to Operator", "Link to Supplier").

User flow:

  1. User clicks action
  2. Modal opens with a table/tree
  3. User selects object(s) from modal
  4. Method executes with selected object

6. getSelectedObjectForPanelId

Get all currently selected objects from a specific panel by its ID.

json
{
  "objects": [
    {
      "getSelectedObjectForPanelId": "sidebar-panel-id"
    }
  ]
}

When to use: Multi-panel workflows where you need objects from a different panel.

Difference from selectPanel:

  • selectPanel: Opens a modal for selection
  • getSelectedObjectForPanelId: Uses existing panel's current selection

7. getFromActionId

Get object IDs from another action's context (action chaining).

json
{
  "objects": [
    {
      "getFromActionId": "create-batch-action"
    }
  ]
}

When to use: Chaining actions where the first action creates/modifies objects and the second processes them.

Example: Create batch → Start batch production

Understanding idSource

When working with linked objects, each selection contains two GUIDs:

  • link.objectGuid - The link entity ID (the relationship)
  • linkedObject.objectGuid - The target object ID

The idSource property lets you choose which one to use.

When to Use Each Option

Use idSource: 'link' when:

  • Deleting link entities
  • Operating on the relationship itself
  • Methods that expect link GUIDs

Use idSource: 'linkedObject' (default) when:

  • Operating on the linked object's data
  • Most standard CRUD operations
  • Methods that expect object GUIDs

Examples

Delete a link (keep both objects):

json
{
  "request": {
    "parent": "Link",
    "methodName": "deleteLink",
    "objects": [
      {
        "getFromItem": true,
        "idSource": "link"
      }
    ]
  }
}

Update linked object data:

json
{
  "request": {
    "parent": "Product",
    "methodName": "updatePrice",
    "objects": [
      {
        "getFromItem": true,
        "idSource": "linkedObject"
      }
    ]
  }
}

Omit idSource (defaults to linkedObject):

json
{
  "objects": [
    {"getFromItem": true}
  ]
}

Which Strategies Support idSource?

  • getFromItem
  • getFromCreatedObject
  • getSelectedObjectForEventId
  • selectPanel
  • getSelectedObjectForPanelId
  • getFromActionId (returns already-resolved IDs)
  • objectId (you control the GUID directly)

Real-World Scenario

Problem: Delete a Product-Supplier link without deleting the Product or Supplier.

Solution:

json
{
  "id": "remove-supplier-link",
  "method": "runMethod",
  "label": "Remove Supplier",
  "request": {
    "parent": "Link",
    "methodName": "deleteLink",
    "objects": [
      {
        "getFromItem": true,
        "idSource": "link"
      }
    ]
  }
}

Without idSource: 'link', it would try to delete the Supplier object instead of the link!

Editor Configuration

The editor property adds a form before executing the method.

Without Editor (Direct Execution)

json
{
  "method": "runMethod",
  "request": {
    "parent": "ProductionOrder",
    "methodName": "startProduction",
    "objects": [{"getFromItem": true}]
  }
}

User flow: User clicks → Method executes immediately

Direct execution is selected when the editor property is omitted. An editor with an empty fields array is still an editor and opens the modal, so omit the property entirely for methods that do not require input.

With Editor (Form Before Execution)

json
{
  "method": "runMethod",
  "editor": {
    "mode": "modal",
    "header": {
      "title": "Assign to Operator"
    },
    "fields": [
      {
        "attribute": "operator",
        "label": "Operator",
        "type": "Object",
        "required": true,
        "propertyAsId": "itemId",
        "selectPanel": {
          "panel": {
            "id": "operator-select",
            "type": "table",
            "request": {"metaTypeName": "Operator"}
          }
        }
      },
      {
        "attribute": "priority",
        "label": "Priority",
        "type": "String",
        "required": true
      }
    ]
  },
  "request": {
    "parent": "ProductionOrder",
    "methodName": "assignOperator",
    "objects": [{"getFromItem": true}]
  }
}

User flow: User clicks → Modal opens → User fills form → Submits → Method executes

Response Actions

Execute additional actions after the method succeeds. runMethod supports response actions from two places:

  • the /MetaMethods/Run response, when the backend returns an actions array
  • the JSON action configuration, through response.actions

Both sources use the same action processor. Backend actions run first, then client-configured actions run. If the method was executed for selected objects, each response action runs once per resolved object; if there are no resolved objects, response actions run once in the current panel context.

Server Response Actions

A backend method can return one response object or an array of response objects. Each response object may include actions:

json
{
  "actions": [
    {
      "method": "reloadEntities",
      "panels": [{"panelId": "orders-table"}]
    },
    {
      "method": "showNotification",
      "severity": "success",
      "message": "Orders were updated"
    }
  ]
}

Use this when the backend result should decide what the UI does after /MetaMethods/Run, for example refreshing a panel that changed or showing the exact message produced by the method.

Client-Side Response Actions

Use response.actions when the follow-up behavior is known from the JSON configuration:

json
{
  "request": {...},
  "response": {
    "actions": [
      {
        "method": "reloadEntities",
        "panels": [{"panelId": "orders-table"}]
      },
      {
        "method": "showNotification",
        "severity": "success",
        "message": "Method completed"
      }
    ]
  }
}

Supported response actions:

reloadEntities

Refreshes panel data after a method changes objects. Configure panels when a specific panel must reload:

json
{
  "method": "reloadEntities",
  "panels": [{"panelId": "orders-table"}]
}

If panels is omitted, the current panel is refreshed. Tree panels can also reload a selected tree node through treeNodes:

json
{
  "method": "reloadEntities",
  "treeNodes": [
    {
      "getFromItem": true,
      "reloadSelf": true,
      "reloadChildren": true
    }
  ]
}

After response actions finish, runMethod also performs its normal current-panel refetch. Use reloadEntities when another panel or a specific tree node must refresh.

showNotification

Shows a localized toast by default:

json
{
  "method": "showNotification",
  "severity": "success",
  "summary": "Method completed",
  "message": "Objects were updated",
  "life": 5000
}

Supported fields:

  • message: required message text or localized string
  • severity: success, info, warn, or error; default is info
  • summary: optional toast header or modal title
  • life: toast lifetime in milliseconds; default is 5000
  • mode: toast or modal; default is a toast
  • closeLabel: modal close button text; default is Close / Закрыть

Use mode: "modal" when the message must stay visible until the user closes it:

json
{
  "method": "showNotification",
  "mode": "modal",
  "severity": "info",
  "summary": "Server message",
  "message": "Review this result before continuing"
}

When either server or client response actions include showNotification, runMethod suppresses its generic success toast so users do not see duplicate success messages.

Usage Examples

Example 1: Simple Direct Execution

Start production for selected orders (no form).

json
{
  "id": "start-production",
  "method": "runMethod",
  "label": "Start Production",
  "icon": "pi pi-play",
  "request": {
    "parent": "ProductionOrder",
    "methodName": "startProduction",
    "objects": [
      {"getFromItem": true}
    ]
  }
}

Example 2: With Form Editor

Assign orders to an operator with priority.

json
{
  "id": "assign-operator",
  "method": "runMethod",
  "label": "Assign to Operator",
  "editor": {
    "mode": "modal",
    "header": {"title": "Assign Orders"},
    "fields": [
      {
        "attribute": "operator",
        "label": "Operator",
        "type": "Object",
        "propertyAsId": "itemId",
        "required": true,
        "selectPanel": {
          "panel": {
            "id": "operators-select",
            "type": "table",
            "request": {"metaTypeName": "Operator"}
          }
        }
      },
      {
        "attribute": "priority",
        "label": "Priority",
        "type": "String",
        "required": true
      }
    ]
  },
  "request": {
    "parent": "ProductionOrder",
    "methodName": "assignOperator",
    "objects": [{"getFromItem": true}]
  }
}

Example 3: Multi-Source Objects

Link orders from two different panels.

json
{
  "id": "link-orders",
  "method": "runMethod",
  "label": "Link Orders",
  "request": {
    "parent": "OrderRelation",
    "methodName": "createRelation",
    "objects": [
      {"getFromItem": true},
      {"getSelectedObjectForPanelId": "related-orders-panel"}
    ]
  }
}

Result: Combines objects from current selection + sidebar panel selection.

Example 4: Event-Triggered Action

Run method from a notification click.

json
{
  "id": "approve-from-notification",
  "method": "runMethod",
  "label": "Approve",
  "request": {
    "parent": "Approval",
    "methodName": "approve",
    "objects": [
      {"getSelectedObjectForEventId": "approval-notification--on-click"}
    ]
  }
}

Example 5: Action Chaining

First action creates a batch, second action starts it.

Action 1: Create Batch

json
{
  "id": "create-batch",
  "method": "runMethod",
  "label": "Create Batch",
  "request": {
    "parent": "ProductionBatch",
    "methodName": "createBatch",
    "objects": []
  }
}

Action 2: Start Batch

json
{
  "id": "start-batch",
  "method": "runMethod",
  "label": "Start Batch",
  "request": {
    "parent": "ProductionBatch",
    "methodName": "startBatch",
    "objects": [
      {"getFromActionId": "create-batch"}
    ]
  }
}

Best Practices

1. Use getFromItem for Standard Actions

Most actions operate on user-selected items:

json
{"objects": [{"getFromItem": true}]}

2. Combine Multiple Sources When Needed

json
{
  "objects": [
    {"getFromItem": true},
    {"objectId": {"objectGuid": "config-object-id"}}
  ]
}

3. Don't Add Empty Editors

Bad:

json
{
  "editor": {"mode": "modal", "fields": []},
  "request": {...}
}

Good:

json
{
  "request": {...}
}

4. Leverage Response Actions

Chain operations for better UX:

json
{
  "request": {...},
  "response": {
    "actions": [
      {"method": "reloadEntities", "panels": [{"panelId": "main-table"}]},
      {"method": "showNotification", "severity": "success", "message": "Success!"}
    ]
  }
}

Use mode: "modal" when the user must close the message explicitly:

json
{
  "actions": [
    {
      "method": "showNotification",
      "mode": "modal",
      "severity": "info",
      "summary": "Server message",
      "message": "Read this message before continuing"
    }
  ]
}

5. Use idSource Correctly

  • Deleting links? Use idSource: 'link'
  • Updating objects? Use idSource: 'linkedObject' or omit (default)

Common Issues

Issue: No Objects Sent to Backend

Symptom: Method executes with empty objects: []

Causes:

  1. No objects selected in panel
  2. Wrong panel ID in getSelectedObjectForPanelId
  3. Event ID doesn't match
  4. Action ID doesn't exist in getFromActionId

Solution:

  • Verify user has selected items
  • Check panel IDs match exactly
  • Verify event IDs match panel configuration

Issue: Wrong Object Deleted

Symptom: Deleted the Supplier instead of the Product-Supplier link

Cause: Missing idSource: 'link'

Solution:

json
{
  "objects": [
    {
      "getFromItem": true,
      "idSource": "link"
    }
  ]
}

Issue: Duplicate Objects in Request

Symptom: Same object ID appears multiple times

Cause: Multiple strategies resolve to the same object

Solution:

  • Deduplication happens automatically
  • Review your objects array to avoid redundant strategies

Issue: Action Chain Broken

Symptom: Warning "failed to resolve from store"

Causes:

  1. First action hasn't run yet
  2. First action already completed and store disposed
  3. Action ID typo

Solution:

  • Ensure correct action execution order
  • Check action IDs match exactly
  • Verify store lifecycle timing