2 Understand the Building Blocks of Visual Applications

To develop applications with Oracle Visual Builder, you need to understand a few basic concepts.

About the Building Blocks of Visual Applications

The basic components of a visual application are mobile applications, web applications, service connections, business objects, and sometimes processes.

The basic building blocks of a mobile or web application are user interface (UI) components, variables, action chains, page flows and page navigation, and data access through REST endpoints.

The building blocks and their interactions can be summarized as follows.

  • Variables are the mechanism used to store and manage client state. Every variable has a type and a scope.

  • An action chain is composed of a set of one or more individual actions. The action chain is triggered by an event. (For example, a button click can trigger navigation to a page.) Each action represents a single asynchronous unit of work. An action chain can define input parameters and local variables that are available only in the context of that action chain, and can also access application-scoped input parameters and variables.

  • Page flows and page navigation govern the transmission of information from one page to another. Each individual page has a lifecycle, as does an application. Each lifecycle event (entry or exit from a page, for example) can provide a trigger for an action chain.

  • A UI component encapsulates a unit of user interface through a defined contract – specifically, the Oracle JavaScript Extension Toolkit (JET) components contract. Component attributes are bound to variables, and component events and variable changes trigger action chains.

  • All data entering a mobile or web application is based on REST. This data can come from custom business objects and from business objects provided by service connections. Actions and variables control how data is sent to and from a REST endpoint in a mobile or web application. A developer can create a type that matches the REST payload and pass the data using a variable of that type.

The following figure shows the interactions among these building blocks.


Description of bb-interactions.png follows
Description of the illustration bb-interactions.png

Understand Variables

A variable is the basic building block for managing client state. It is of a specific type and exists in a specific scope.

A scope defines the lifecycle of a variable, and the framework automatically creates and destroys the variables depending on the semantics of the scope. The following scopes are supported.

  • Page scope: State is accessible only within the context of the specified page. All state is initialized with default values when the page is entered, and destroyed when the page is exited.

  • Application scope: State is accessible in all parts of the application and in all pages.

  • Flow scope: State is accessible in all pages contained in the current flow.

  • Action chain scope: State is accessible in the current action chain.

Variables store intermediate state on the client between the Visual Builder user interface and REST services. Components are principally bound to these variables, and the behavior of the variables is governed by actions.

A variable's type can be a primitive, a structured type (which can consist of other types), a dynamic type, or a builtin type.

A variable value that has not yet been instantiated is undefined. A variable is guaranteed to be instantiated and its initial value set just before the vbEnter event is raised (see The Lifecycle of a Page).

The initial value of a variable is determined using the defaultValue property set on the variable, along with its type.

When its value changes, a variable emits an event. This event may trigger an action chain. You can define variables as input parameters, with their value determined by the inputs to the page or module. These inputs can be URL parameters for bookmarking, for example.

For more information on variables, see Variables.

Variables and Parameter Passing

You can use a variable to pass a parameter between pages. You can mark a page variable as an input, specifying how it becomes part of the contract in order to navigate to that page. You can then further mark it as required, implying that it must be set in order to navigate to that page.

The following table lists the available properties for variables.

Property Required? Description
type Yes A specific primitive type (string, boolean, number,and so on); a structured type such as an array or object, for which each field can either be a primitive or a structure; a dynamic type (any); or a built-in type, such as ServiceDataProvider or ArrayDataProvider (see Built-in Types).
input No; applicable only if the property is within the page scope How the variable becomes part of the page contract for incoming navigation. The value is either none (the default), fromCaller (indicating that it will be passed internally), or fromURL (indicating that it will be passed via the URL).
required No Whether or not the variable must be set
defaultValue No The default value for the variable to be initialized. If no default value is provided, the value is "not set" or undefined. The defaultValue can be bound to an expression, or it can be a structure that uses expressions that reference other variables.
persisted No Use persisted variables when you want the lifespan of the variable to be longer than the page. For example, an authorization token can be kept for the duration of a session. This ensures that even if the page is refreshed, the token will still be available throughout the session. To store a variable across sessions, use "device" instead of "session". The variable itself still exists only in its defined scope. Can be set to the following values:
  • session: This property will be applied when entering the page, but only during the current browser session.

  • history: The variable value is stored on the browser history. When navigating back to a page in the browser history using the browser back button, the value of the variable is restored to its value at the time the application navigated away from this page.

  • local: The variable is stored in the browser local storage so persisted on the device where the application is running even if the browser is closed.

Expressions

An expression may refer to other variables, system properties, statics, and the like. For example:

$variables.total = $variables.sum * (1 + $variables.taxRate)

The Visual Builder user interface performs dependency analysis of the expressions to correctly order expression evaluation and detect cycles.

If the value of any variable referenced in an expression changes, the expression is immediately reevaluated.

An expression can be used in the default value of a variable.

You can use the following implicit objects in expressions. All are prefixed by a dollar sign ($).

Name Where Available Description
$application Everywhere The application object
$page In the current page The current page instance
$variables Every scope that has a variables property A shortcut for $most_specific_scope.variables in the current scope. In a page, $variables is a shortcut for $page.variables.
$chains Every scope that has a chains property A shortcut for $most_specific_scope.chains
$chain Actions executing in an action chain The chain in which the action is executing
$parameters In the beforeEnter event The input parameters for the page. This object is needed because page variables do not exist yet in the vbBeforeEnter event.
$listeners In a flow or page The event listeners of a flow or page
$event Event listeners and variable onValueChange listeners For an event listener on a component, $event contains the Event JavaScript object that the component passes to the listener. For an event listener on a custom event, $event contains the payload for that event. For an onValueChange listener on a variable,$event is a structure with the properties name, oldValue, value, and diff (itself a structure).

Variables and Lifecycles

Application and page variables are constructed automatically in a specific application or page lifecycle stage.

Input parameters that are passed by means of navigation rules, or bookmarkable variables that are provided on the URL, are automatically assigned to their corresponding variables. When you modify the value of a bookmarkable variable, the URL is automatically adjusted to match that new value (that is, a new history state is pushed). In this way the page is always bookmarkable and does not require any specific user action in order to be bookmarked.

Variables and Events

A variable triggers an onValueChanged event when it is modified. This event is triggered only when the value is actually changed; setting a variable value to the same value does not trigger an event. The variable must be explicitly changed to send the event. For example, if a variable is a complex type, modifying an inner property does not fire this event; the entire variable must be set by means of an API call. In this case, the framework can add to the payload those parts of the structure that have changed. For example, if you changed the name property of an Employee and then reset the Employee, the framework would send an event that the Employee changed, and as part of the payload indicate that the name has changed.

An onValueChanged event can trigger a user-defined action chain. The trigger has the payload of the former and new values of the variable.

For more information, see Understanding Actions and Action Chains.

Understand Actions and Action Chains

An action chain is made up of one or more individual actions, each of which represents a single asynchronous unit of work. Action chains are triggered by events.

An action chain, like a variable, has a scope: it can be defined at the application level or the page level. You can call an application-scoped action chain from any page. You can call a page-scoped action chain only from the page on which it is defined.

To create an action chain, you can define your own actions and can also use predefined actions. Actions within a particular chain run serially, and multiple action chains can run concurrently. Action chains simplify the coordination of asynchronous activities.

A single event may simultaneously trigger multiple action chains. For example, the page enter event may trigger multiple data fetch action chains simultaneously.

An action is a specific function that performs a task. In JavaScript terms, an action is a Promise factory. An action can exist only within an action chain, not independently.

Action Chain Context and Contract

Action chains have a well-defined context and contract: an action chain orchestrates its underlying actions, coordinating state flow and the execution path. The action chain can define input parameters and local variables that are only available in that context. An example of an action chain is one that makes a REST call (first action), then takes the result of that and stores that in a variable (second action).

An action chain maintains its own context, which is accessible through an implicit object called $chain. Actions may export new state to that context, but it is only available to future actions along that same action chain. An action chain can be created in the context of a page or the application and exists within the scope of the page or the application. It has a defined interface and contract and can be called by event triggers using its ID.

The action chain contract has three parts.

Action Chain Part Description
ID String identifier for the action chain
Input parameters Zero or more variables that can be passed into the action chain and added to the action chain context
Variables Zero or more variables that are internal to the action chain and usable internally by actions

For more information, see Action Chains.

Predefined Actions

The predefined actions for an action chain include Navigate to Page and Assign Variables. An action has the following parts that the developer can define.

Action Part Description
ID String identifier for this action instance. This action part is optional, since the ID is necessary only if you wish to refer to the action’s results later in the action chain.
Configuration Any properties of the action that the user can configure. For example, for the Navigate to Page action, the page to navigate to and any parameters required for that navigation.
Outcomes and Results An action may have multiple potential outcomes (such as success or failure, or a branch). It can also return results.
Exported State An action may export state that is available to future actions within the context of the same action chain.

The predefined actions include conditionals and other processing instructions. For example, you can use if and switch actions that take an expression and offer multiple different chain continuations depending on the result.

For details about predefined actions, see Actions.

Event Handling for Action Chains

Action chains are defined at the application or page level and triggered by a specific event, such as onValueChange (for a variable), or vbEnter. An event may include a payload, which can then be used within the action chain. A payload may be passed into an action chain through the input parameters. The Visual Builder user interface can help you create action chains automatically (with appropriate input parameters) based on a particular event.

Understand Page Flows and Lifecycles

The page flow governs how information is transferred between pages. The page lifecycle governs the state of an individual page.

A page has a defined lifecycle that permits you to listen to certain events that are triggered as part of the lifecycle. Examples of page lifecycle events are enter and beforeExit.

One or more pages form a page flow. Within a flow, you can set up navigation from page to page.

Navigation actions can be internal or external. An internal navigation action is composed of the ID of the page to navigate to along with any parameters that are specified for that page. An external navigation action is defined by an external URL. These actions are defined in the page model.

An application also has a lifecycle and flow. An application can contain multiple page flows.

The Lifecycle of a Page

An individual page has defined lifecycle states upon entering and leaving, and each state has a trigger. For some states, you can provide action chains in response to the triggers. Other states are internal, but help illustrate what happens and when in the system.

Event Applies To Can Cancel Navigation Event Payload Returns Description
vbBeforeEnter Page Yes Previous route, sanitized input parameters Typed state Dispatched to a page before navigating to it. Visual Builder will navigate to this page, but has not yet started the navigation and has not torn down the previous page's state.

A developer can cancel navigation for this event (for example, if the user does not have permission to enter this page) by returning an object with the property cancelled set to true. A developer can also redirect the user to another page instead (for example, it can take the user to a login screen).

For success cases, this can return some state that can be passed into the vbEnter state.

After this state is exited, the previous page’s state can be torn down.

Application state is available on a read-only basis. No page state is available.

The following variable scopes are available:

  • $application: All application variables
  • $flow: All parent flow variables
  • $parameters: All page input parameters from the URL
vbEnter Page or flow No State from vbBeforeEnter None Dispatched after all the page-scoped variables have been added and initialized to their default values, values from URL parameters, or persisted values.

The following variable scopes are available:

  • $application: All application variables
  • $flow: All parent flow variables
  • $page: All page variables

This state is generally used to trigger data fetches, which may occur concurrently.

vbBeforeExit Page Yes None Typed state Dispatched to a page before exiting it. After all action chains triggered by vbBeforeExit complete, the Page instance is destroyed and future access to that Page instance will throw an exception.

A developer can cancel navigation for this event by returning to the listener chain an object with the property cancelled set to true. This can be useful if the page has to be saved before the user exits it.

vbExit Page or flow No State from vbBeforeExit None Dispatched when exiting the page. This event can be used to clean up resources before leaving the page.

Page Navigation

Every page in the application has a name, which you can specify and change. You use the page name to navigate from one page to another within a page flow.

To configure a Navigate to Page action, specify the following parameters:

  • The page to navigate to, or an expression that resolves to that value

  • Values for required input parameters and for any optional parameters that you use

There are two possible results:

  • Navigation was successful

  • Navigation was cancelled from the page we are navigating to

Understand UI Components

User interface (UI) components encapsulate a unit of user interface interaction through a defined contract.

The Web Component contract exposes the functionality of a component through the user interface, enabling the component to interact with other parts of the application. Visual Builder supports the Oracle JavaScript Extension Toolkit (JET) components contract, which adds data binding, component metadata, and dependencies on top of the Web Component contract. The Oracle JET components contract exposes a custom Document Object Model (DOM) HTML element with custom properties, events, and methods. The property binding added by Oracle JET supports both one-way (read-only) and two-way (read/write) binding. In general, the component properties are bound to variables, and the component events trigger action chains.

A component can have zero or more slots that can hold one or more children of that component. For example, a toolbar can contain a number of buttons.

You can add components to an application from the Component Palette. You can also use custom JET components, including those supplied by the Component Exchange. See Work with the Component Exchange for details.

For simple use cases, you can use a simple HTML component and corresponding view model implementation.

For details about Oracle JET, see http://www.oracle.com/webfolder/technetwork/jet/index.html. The Oracle JET Cookbook provides detailed information about using all the supported components at http://www.oracle.com/webfolder/technetwork/jet/jetCookbook.html

The Component Contract

A UI component, whether shipped by Visual Builder, provided by a partner, or created by you, must follow the same component contract. This contract allows Visual Builder to expose the functionality of a component declaratively through the Visual Builder user interface. If you need to add functionality to a component, you can expand the capabilities of that component, and the new functionality is then expressed in that component’s interface.

The component contract has four aspects: properties, events, child slots, and methods.

Properties

A component has properties that you can bind to variables or expressions by means of the Visual Builder user interface. These properties can affect the state of a component (for example, the value of an input text field) or affect its rendering (for example, enabled or disabled). A component property has a specific type, which matches the types available for a variable, and may itself be structured or a collection. A property may also be required as part of the component interface.

In addition to a type, a component property may also have additional metadata (as defined in the JET design time metadata for properties), such as a display name or description.

There are two kinds of properties, one-way and two-way.

Property Type Description Can Be Bound To
One-way (read-only) The component reads the value of this property. If the expression that the property is bound to changes, the component will be notified of this change. Expressions (which may contain variables)
Two-way (read/write) The component can read the value of this property and can also write back to that property. If the variable is modified externally, the component will be notified of this change. Variables

Events

A component can fire zero or more events (for example, an onClick event for a button). Each event has a payload. The Visual Builder user interface allows the developer to listen for any of these events and to expose the event payload. An action chain can then process the event.

Child Slots

A slot is a placeholder inside a web component that you can fill with your own markup. A component can have zero or more slots that can hold one or more children. Any children not assigned to a specific slot are assigned to the default slot.

Methods

A component can have zero or more methods that can be called on the component to perform an action (for example, to flip a card). These methods may have parameters that are defined as part of the component interface. The Visual Builder user interface provides an action within an action chain that allows the user to call a component method and fill in the parameters using expressions.

Component IDs and Styles

A component can have a configurable ID to allow it to be referenced from an action. In addition, you can bind component style classes to an expression.

Understand Data Access Through REST

All data access to and from a client application occurs through REpresentational State Transfer (REST) calls.

The Visual Builder user interface provides access to two basic kinds of data:

  • Custom business objects internal to Visual Builder, which you can create yourself and use in applications

  • Business objects accessed through service connections, which you can set up to access external web services

When you create a custom business object, a REST API is automatically created for you, with GET, POST, PATCH, and DELETE endpoints.

When you create a service connection, you can obtain REST APIs in one of the following ways:

  • Select objects from a service catalog

  • Provide a service specification document in OpenAPI/Swagger or Oracle Application Developer Framework (ADF) Describe format

  • Specify an endpoint URL, an HTTP method, and an action hint

Each of these mechanisms generates REST APIs for you to use. You can specify request and response payload structures in JSON format, and you can provide a subset of query parameters to expose to the Visual Builder user interface. Parameters can have a type (but are assumed to be primitives). You can also use the provided REST helper utility to call REST endpoints.

For full details on using REST for data access in Visual Builder, see Accessing Business Objects Using REST APIs.

Data Binding

You can create variables and action chains to call REST endpoints from your applications, retrieving and sending data to and from the endpoints. Typically, the type of the variable matches the structure of the REST payload. You have the option of defining your own type that more closely matches your use case, and then mapping from the REST payload to a variable instance that uses that type. For example, for advanced cases, you could define a variable type that matches your own page design, and then map one or more REST payloads to that type. To send that data back to a service or services, you would again map the data of that variable to the REST payloads.

Components are bound to variables. These variables do not have any intrinsic knowledge of where their data is derived from or what their data is used for. To populate a variable from a REST call, you assemble an action chain from an action making that REST call and an action assigning the result to that variable. In the common case, the Visual Builder user interface automates the creation of that variable to match the payload of the REST call, enabling you to quickly bind the REST call's payload in your application pages. To handle a POST or DELETE action, you compose an action chain with the REST action, passing in the variable as the payload.

Mapping to and from REST

In more advanced cases, you may wish to define a model (through the use of a variable) that more closely matches your specific application. In other cases, the GET and POST (or equivalent methods) may be asymmetrical or may be from different services entirely. In these cases, you can map the REST payload to and from that variable.