Submission data

Typically, the handling of an event will consist of three steps:

  1. Get input data provided by the user.
  2. Perform calculations.
  3. Send a result back to the user.

In Simian GUI, data is communicated via submission data. In particular when working with nested forms, the submission data can have a deeply nested structure, which makes it cumbersome to work with directly. Therefore, Simian GUI provides some utility functions to address this issue. It is therefore advised to refrain from getting and setting the submission data in your payload directly, and to stick to using these functions:

getSubmissionData: Obtains submission data from the payload using the component key. You can use this to, for example, get the text entered in a specific textfield. Note that for some components the submission data values are (or can be) automatically converted to a more user-friendly format.

setSubmissionData: Sets submission data using the component key. If there is already submission data present for the component, it will be replaced. Use this, for example, to set the text of a specific textfield or to fill a datagrid. This function may apply changes to the input data to make sure it is understood by the front-end. The changed input data is the second output of the function. For example, setting the submission data of a DataGrid component allows for entering the data as a numeric list/array. However, this is transformed into a list of dicts/struct array before being placed in the submission data.

These functions should not be used during initialization (gui_init), but are there for event handling.

The components for which the data type is (or can be) automatically converted in the getSubmissionData and setSubmissionData functions and the corresponding data types are:

ComponentSubmission datagetSubmissionData outputsetSubmissionData input
DataGridlist of dicts / struct arrayDataFrame / table (opt.)table-like
DataTableslist of dicts / struct arrayDataFrame / table (opt.)table-like
DateTimestring- / datetime- / datetime, string
Daystring- / datetime- / datetime, string
EditGridlist of dicts / struct array- / table (opt.)table-like
Plotlydict / structutils.Plotlyutils.Plotly

with:

  • 'x / y': Python / MATLAB data types. When there is a difference.
  • '-': no conversion.
  • '(opt.)": optional conversion output type.
  • 'table-like': DataFrame, list of dicts, dict with lists, list of lists / table, struct array, 2D-matrix

Syntax

data, is_found = utils.getSubmissionData(payload, key, nested_form, parent)
payload, new_data = utils.setSubmissionData(payload, key, data, nested_form, parent)
[data, isFound] = utils.getSubmissionData(...
    payload, key, "NestedForm", nestedForm, "Parent", parent);
[payload, newData] = utils.setSubmissionData(...
    payload, key, data, "NestedForm", nestedForm, "Parent", parent);

Arguments

  • payload: the payload contains the submission data
  • key: the component key for which the value will be retrieved
  • data: the value of the specified component. When using setSubmissionData in Python ensure that the values are JSON serializable with the json module. This may require converting values to another data type before using it in setSubmissionData.
  • isFound: boolean value indicating whether the submission data has been found
  • optional NestedForm: when working with nested forms, the key of the form can be specified. This input can be omitted if the component is not in a nested form or if the combination of key and Parent is unique within the application.
  • optional Parent: key of the parent component. Use this for components in Containers, DataGrids, Panels, etc. Some additional notes about this input argument:
    • This must be the key of an actual component. For example, if you want to get or set the submission data for a component that is in a tab of a Tabs component, this input shall be the key of the Tabs component and there is no need to specify which tab the component is in. Similarly, for a component in a Columns component, you can provide the key of the Columns component and do not have to specify which column the component is in. This is different from the form initialization code, where a single tab or column can be provided as the parent when adding a component to it.
    • If a component is directly in a nested form, do not input the nested form's key as the parent. Instead, use the NestedForm input for this.
    • This input can be omitted if the component does not have a parent component or if the combination of key and NestedForm is unique within the application.

As described above, if there are multiple components with the same key, you can use the NestedForm and Parent inputs to refine the selection. When the component is directly in the form, do not specify a Parent or NestedForm input.

When zero or more than one components match the key(s) in the inputs, the getSubmissionData function will return a None / [] as data, and false for isFound. When exactly one component matches the key(s) in the inputs, the value of the component is returned and isFound contains true. setSubmissionData errors when not exactly one component is matched.

Please note that in Python, the payload dict returned by the setSubmissionData function is the same object as the input payload.

Example

The three steps described at the top of this page are illustrated with an example below.

def estimate(payload: dict) -> dict:
    # Collect input data provided by the user.
    input_value, _ = utils.getSubmissionData(payload, 'my_input_field')

    # Do the calculations.
    output_value = doSomething(input_value)

    # Send the result back to the user.
    return utils.setSubmissionData(payload, 'my_output_field', output_value)[0]
function payload = estimate(payload)   
    % Collect input data provided by the user.
    inputValue = utils.getSubmissionData(payload, "my_input_field");
    
    % Do the calculations.
    outputValue = doSomething(inputValue);
    
    % Send the result back to the user.
    payload = utils.setSubmissionData(payload, "my_output_field", outputValue);
end