Skip to main content

Veritran Docs

[en] Logic Content

[en] This section outlines best practices for building a process inner logic, including the use of functions, conditionals, loops and arrays, navigation logic, transaction and call API invocations, and JSON object manipulation. It also includes best practices for the use of code view when building a process.

[en] Functions allow to encapsulate logic in reusable blocks, helping simplify complex processes and improve code readability.

[en] Best practices when working with functions include:

  • [en] Assign only one responsibility to each function: Each function should carry out a single, well-defined task. If a function is validating, formatting, and calculating at the same time, it is better to split it into smaller functions.

  • [en] Keep functions short: Avoid overly long functions. They should not exceed a reasonable number of actions.

  • [en] Minimize tight coupling: Whenever possible, a function should operate using its inputs and return a result, without directly modifying other parts of the process—unless that is its explicit purpose. Avoid modifying variables outside their context unless absolutely necessary.

[en] Conditional structures allow you to control the application flow based on conditions evaluated at runtime. It is essential to use them clearly and consistently to enhance readability, avoid unnecessary complexity and reduce the risk of logical errors.

[en] Best practices when using conditionals include:

  • [en] Use simple and expressive conditions: Avoid overly long conditions or those with multiple nested logical operators. If a condition becomes complex, consider extracting it into a function with a descriptive name.

  • [en] Use clear boolean condition names: Variables or functions used as conditions should be self-explanatory. For example: hasAvailableBalance instead of flag1.

  • [en] Prioritize readability: Order conditions based on clarity or likelihood. In multi-branch conditionals (if/else if/else), place the most common or relevant cases first.

  • [en] Avoid deep and unnecessary nesting: Too many nested conditionals make the flow hard to follow. Consider simplifying with intermediate functions or separate blocks.

    Nota

    [en] As lambda processes do not currently support early returns, you can use nested “else if” statements as an alternative.

  • [en] Consolidate similar conditions: If multiple branches share similar logic, consider grouping them to avoid duplication.

  • [en] Handle all possible cases: Ensure all expected scenarios are covered with else blocks or additional validations. This is especially important to avoid unexpected results or incomplete flows.

  • [en] Avoid UI logic in business conditionals: Separate the logic that drives business decisions from logic affecting the interface (e.g., showing or hiding components, applying styles).

  • [en] Document complex rules with clear names or minimal comments: When a condition unavoidably combines multiple business rules, include a brief explanation. If possible, encapsulate it in a clearly named function.

[en] This section outlines best practices for working with repetitive data structures like lists and arrays, and for building iterative logic using loop-type blocks. These allow you to go through, filter, and transform lists in a clear and efficient way.

[en] Best practices when using loops include:

  • [en] Use the for (index) from (0) to (0) do block when the number of iterations is known and you need to access the iteration index (e.g., processing by position or accessing multiple arrays in parallel).

  • [en] Use the for element block when iterating over a list without needing the index—ideal for operations like filtering or mapping where you work directly with each item (see filtering template).

  • [en] Use the while do block when the loop condition is dynamic and not based on a fixed number of iterations.

[en] Best practices for operations using arrays include:

  • [en] Get array length: Use the length of array [] block to get the length of an array. This is the standard method to determine the size of an array.

  • [en] Search (find first): There is no built-in block for this, so you must implement it manually. As you need the index for this operation, use the for (index) from (0) to (0) block to obtain it.

  • [en] Filter: Similarly, filtering must be built manually using a loop. Since filtering is about retrieving full rows rather than specific indexes, use the for element block to do so.

  • [en] Obtain cell value: To retrieve the value of a cell, use the array table value block. The #A expression should not be used.

[en] The navigation and interaction with the UI are defined through Next blocks.

[en] Except for the execute inline lambda block, Next blocks are not executed at the moment they are declared. Instead, they are queued and triggered at the end of the process. In other words, they do not pause or interrupt the flow; they are collected during execution and executed only after the process completes.

[en] Best practices when using Next blocks include:

  • [en] Avoid using the “command” block, except in cases where no specific block exists (e.g., invoking functional flow modules or system popups).

  • [en] Avoid using variables or registers as values in Next blocks. Doing so limits the ability to track usage using the Used in feature. In cases where this is unavoidable (e.g., when logic can be invoked from multiple sources and must return to the origin), clearly document the reason.

  • [en] Declare the Next block at the logical moment when the navigation is required, even though its execution will occur at the end. This eliminates the need for temporary variables used solely to handle later navigation.

  • [en] In group or component blocks, the available events are generic. However, it is possible to add other events allowed for the type, even if they are not listed by default.

[en] As mentioned in the Model Structure section, it is recommended to encapsulate the transaction invocation within a specific function that also includes error handling. This helps standardize implementation and simplifies maintenance.

Importante

[en] Best practices for transactions error handling are still being developed.

[en] Best practices when invoking transactions include:

  • [en] When naming the function that invokes the transaction, use the prefix invokeTrx + code or a descriptive name (e.g., invokeTrx2054 or invokeTrxGetAccounts).

  • [en] Assign the transaction contract (block) to a variable. Define a variable named trx + code or a representative name (e.g., trx2054 or trxGetAccounts).

  • [en] Place error handling between the assignment of the transaction contract and the execution. This allows for validating specific conditions for each transaction.

  • [en] Use the execute transaction block to invoke the transaction.

  • [en] Avoid redundant input assignments. If the input register is the same as the register containing the value to be sent, leave the value as " ". In this case, the corresponding register value will be automatically used.

  • [en] Verify that the transaction exists in the branch linked to the app or module. This is crucial when importing processes from another environment or after performing merges or dependency changes.

[en] Lambda processes allow defining a transaction execution as asynchronous, which can be useful in scenarios where waiting for a response is unnecessary, or when you want to improve your app performance. Async transaction execution should be used when the transaction response is not relevant to the user's immediate flow, and in logging, tracking, notification, or auditing processes that should not block user interaction.

Importante

[en] Async transaction executions are not available in Webfly.

[en] Some important considerations when using async transaction executions include:

  • [en] Do not implement logic that depends on the immediate result.

  • [en] Avoid continuing with logic that assumes the transaction has already returned a result.

  • [en] Include post-processing logic if needed. If an action must be taken based on the result, create a separate process to handle it.

  • [en] Avoid using async transactions for critical validations. In processes where the transaction determines whether to proceed (e.g., login, limit validation), always use synchronous execution.

  • [en] Use the prefix trxAsync when naming the variable.

  • [en] Avoid simultaneous transaction invocations. Regardless of the invocation type (sync or async), transactions are queued on the device, meaning only one executes at a time.

    Importante

    [en] In iOS apps, if multiple async transactions are invoked, only the last next action is executed.

[en] Call APIs allow the interaction with third-party services or native device features (e.g., camera, biometric reader, or notifications).

Importante

[en] Best practices for call APIs error handling are still being developed.

[en] Call APIs use a predefined range of registers for input and output data:

  • [en] Input registers: 390 to 399

  • [en] Output registers: 290 to 299

[en] There are currently three blocks available for invoking a Call API:

  • [en] execute call api

  • [en] execute call api ( ) and response code

  • [en] execute call api < > and response success

[en] As with transactions, it is recommended to encapsulate the call API invocation within a dedicated function that also handles errors. This standardizes implementation and simplifies maintenance.

[en] Best practices when invoking call APIs include:

  • [en] When naming the function that executes the call API, use the prefix invokeCallAPI + code or a descriptive name representing the call API.

  • [en] Assign the Call API to a variable. Define a variable named callAPI + code or a representative name.

  • [en] Use the execute call api block to invoke the call API.

    Importante

    [en] Unlike transactions, error handling in call APIs does not interrupt process execution after the execution block.

  • [en] Return the value of register 112 (API call result) as the function's output. The function can be called directly from a conditional structure (e.g., if), by evaluating the returned result.

  • [en] Ensure the call API is configured in Studio. The specification of the call APIs must be defined in the corresponding configuration file. This is particularly important when importing processes from another environment.

  • [en] Verify the relevant SDK is enabled in Mobile Builder for the binary being used. If it isn’t enabled, the call API will not work and the app could fail.

[en] Lambda processes allow the manipulation of JSON objects, this includes creating and parsing the JSON.

[en] Best practices when manipulating JSON objects include:

  • [en] Avoid manually creating the JSON as plain text.

  • [en] Use consistent and descriptive key names. Avoid ambiguous or generic keys such as value1, param, or data.

  • [en] Document expected structures. Provide documentation or an example of the expected JSON structure in a comment to improve clarity and maintainability.

[en] The lambda processes editor allows you to build logic through a visual programming tool used to build a process by dragging and dropping puzzle-piece shaped blocks into a canvas and arranging them as needed. However, it also offers a second view called Code, which displays a TypeScript representation of the logic created.

[en] It’s important to note that this view does not represent the original source of the logic, but rather an automatically generated translation based on the configured blocks. Thus, it is important to take the following aspects into consideration when using it:

  • [en] Changes made in the Code view are not saved as part of the process.

  • [en] Every time you switch from Blocks to Code view, a new representation is generated from scratch.

  • [en] If you manually modify the code, the system will try to map it back to blocks when returning to the Blocks view, but this mapping may fail if unsupported structures were introduced.

  • [en] Some changes may reorganize the list of statements (such as the on start container block and function blocks) when switching back to Blocks view.

[en] Best practices when using Code view include:

  • [en] Use the Code view as support for reviewing or reading logic, especially when a more linear view of the process is needed.

  • [en] Take advantage of the search and replace option in this view to quickly find references to specific contents such as variables.

  • [en] Use it to compare complex structures (like loops or nested validations) that may be harder to follow in the Blocks view.

  • [en] Copy and paste logic structures when helpful.

[en] When using Code view it is also important to avoid the following:

  • [en] Using code that cannot be represented in blocks (e.g., advanced operators, unsupported function calls, etc.).

  • [en] Relying on the assumption that edited code will be preserved. Changes such as variable definitions may be altered when switching back to Blocks view.