Skip to main content
Version: 2.2

Best practices

Naming conventions

In general, all bricks shall be named using Title Case, with capital letters for all words and spaces between words.

Functions and Actions

Function Names use Title Case, with capital letters for all words and spaces between words.

inputs and outputs are in lowercase, with spaces between words.

Data models

Model Names use Title Case, with capital letters for all words and spaces between words.

properties and relations are in lowercase, with spaces between words.

UI components

Component Name use Title Case, with capital letters for all words and spaces between words.

Properties use Title Case, with capital letters for all words and spaces between words.

UI Components

UI Components have two main purposes:

  • Allow the creation of reusable components
  • Make it easier to layout elements

For example, using a UI Component to store the content of a form allows to easily align the different text fields and form elements. The 'form component' can then be dropped on a screen and resized in a coherent manner, without needing to control each form element individually.

Reusing UI Components: exposing children object properties

It is quite rare that we want to reuse a UI Component as is in multiple locations. In most cases, we want to parameterise in one or both of two ways:

We want to have different texts (or any other property) in the different instances of the UI Component

Customizing texts (or other properties)

When text or other properties of the UI Component's internal UI Elements must be set, use the following approach:

  1. Add a custom property in the Context of the UI Component (e.g. "Form Title")
  2. Map that property to the appropriate UI Component, using the f(x) of the relevant property.

Exposing internal events

Beyond properties, the UI Component's context can define Events.

Those events can be triggered from within the UI Component using Dispatch Event actions.

Within the parent Screen or UI Component, the application can respond to the events by configuring the f(x) on the UI Component's events.

Data

Upon creating a data model, it is recommended to also create a set of helper logic bricks to make it easier to manipulate that data. The standard programming terminology is:

  • Constructors are used to construct objects from a model and the relevant parameters to should be set. We may typically have multiple constructors to accommodate different criteria.
  • Getters are used to retrieve information from an object.
  • Setters are used to modify information within an object.

Those can be created straight from the Data Model Editor.

Summary

Given the following business model:

DataModel

It is good practice to create the following bricks:

  • Constructor: a Create Geolocation action, taking "Longitude", "Latitude" and "Altitude" as inputs, and outputting a persisted "Geolocation" object.
  • Getter: a Geolocation's Attributes function, taking a "Geolocation" object as input, and outputting "Longitude", "Latitude" and "Altitude"
  • Setters: a Set Geolocation's Attributes action, taking a "Longitude", "Latitude", "Attribute" and "Geolocation" as input, and outputting a "Geolocation" object.

Even though you may need to create multiple specialised variants of those bricks, those three base bricks provide a very good starting point. The sections below dive into those elements in a bit more detail.

Constructors

Constructors are logic bricks that typically contain a Create Local Object brick, as well as a few Set Object Property bricks.

More specific names could be:

  • Create Geolocation from City Name
  • Create Temperature from °C

Here is a potential Constructor action for creating a Geolocation object from a Longitude and Latitude:

Constructor

As the number of actions and parameters grows, you may also want to stack the bricks instead (with the drawback of having the Control Flow getting a bit in the way):

Constructor stack

Getters

Getters allow retrieving information from the object. Those can be simple properties (like Latitude in our example above), or higher-level (and often higher-valued as well) information.

Examples:

  • Geolocation's Attributes
  • Geolocation's Latitude
  • Geolocation's Position (might for instance provide only Longitude and Latitude, but not Altitude)
  • Geolocation as String (provides a location with the following format: 46.5172214°N, 6.5621934°E)
  • Geolocation as Address (provides a location with the following format: PSE D, 1015 Ecublens, Switzerland)
  • Temperature as °F (provides a temperature as Fahrenheit)

Here is a sample getter that retrieves a single property:

Getter

Many functions need to retrieve more than one property of an object. As such, it is often more convenient to define a single function that provides all attributes. It is important to note that there is no harm in leaving outputs unconnected within a function. Retrieving all properties at once:

Get all properties

Setters

Setters are used to modify the attributes of an object.

Examples:

  • Set Geolocation's Attributes (when setting all attributes at once)
  • Set Geolocation's Position (when setting both the Latitude and Longitude)
  • Set Geolocation from Address
  • Set Temperature from Fahrenheit

Here is a sample setter:

Sample setter

Pitfalls

Draw still isn't feature complete. This section therefore lists the main limitations and possible workarounds.

Refactoring

Refactoring typically occur on different levels:

  • Reusing a part of a function in another function
  • Updating data models
  • Updating the UI

Data models

When refactoring a Data Model, the following approach is recommended:

Adding a property:

  • Nothing to do here, but don't forget to update the Constructors, Getters and Setters accordingly.

Removing a property

  • In the data model editor, rename the property to "my property OLD"
  • Look for usage of the property using the Spec & Doc editor
  • Update all locations accordingly
  • Once all usages have been removed, delete the property. This will delete all instances of that property in the DB.

Changing a property's type, or refactoring a property into a separate business model is done by combining the approaches above, i.e. by adding the new version and removing the old usage.

UI updates

UI Components are the best way to encapsulate and reuse information.

Scrolling

Lists are scrollable by default. Screens however are not, as they are meant to support apps, which usually have scrolling in specific locations, and not globally for the whole app. If you need a scrollable pane, you must for the moment use UI Components. The simplest approach is the following:

  • Screen contains 1 full screen UI Component, and nothing more
  • Full screen UI Component contains any additional UI Component

Local vs Global objects

By default, the Create Local Object brick doesn't persist the object on the Orchestrator.

Importantly as well, files (typically those coming from Take Camera Picture) must be persisted explicitly.

When building constructors that don't include the Persist operation, we recommend making it explicit by putting 'Local' in the constructor's name: Create Local <<name of business model>>.

Working with multiple browser tabs

It is often very convenient to open multiple tabs or windows to avoid having to switch from one editor to another.

Main logic

Since there is no main loop, we recommend putting general functions (e.g. registration of a listener, starting a Timer, ...) in the screen's On Load function.

Export

We recommend exporting the different bricks (screens, UI components, functions, etc.) individually, in order to make the export granular.

Dependencies

At the moment, Draw supports importing projects into one another. This allows creating one project acting as a library of reusable bricks, which can then be reused across multiple other projects. Versions are not fully functional at the moment, so updates to the library project are immediately reflected in the importing projects as well.

Similarly, double-clicking on an imported function or UI Component will open that function or UI Component for edition in the other project.