Platform Knowledge Base
Comprehensive guides and documentation for designing, building, and managing enterprise applications on the REKA / LEAP platform.
- REKA Beginner Level training completed.
- Familiarity with HTML and JavaScript.
- Understanding of backend (server) and frontend (UI) concepts.
- Reference: REKA Glossary
Select a topic from the sidebar folder navigation to explore the detailed advanced functionalities of the REKA platform.
1. Form Design
1.1 Single Data
The Single Data option ensures that only one record exists for a given qualifier (criteria).
- If no matching data exists → a new entry will be created.
- If matching data exists → the existing entry will be loaded for update.
How to Enable Single Data
- Navigate to the form.
- Click the Edit Form button.
- In the Options tab, enable Single Data.
- Provide a Qualifier in JSON format.
Qualifier
The Qualifier defines the conditions used to check whether a record already exists.
Examples
1. One record per user
{ "$_.email": $user$.email }
2. One record per user per year
{ "$_.email": $user$.email, "$.year": new Date().getFullYear() }
3. Using $prev$ as a qualifier
If you want to tie a record strictly to a specific previous entry's ID:
{ "$prev$.$id": 12, "$.email": $user$.email }
Note: If an entry doesn't exist, a new entry will be created with previous data automatically mapping to $prev$.$id = 12.
- Applies only to special facets:
edit-singleandview-single. - Equivalent behavior can be achieved by using edit with a qualifier parameter:
/form/2123/edit?$_.email={{$user$.email}}
1.2 Previous/Next Form
Overview
This establishes parent-child relationships between form entries in a relational approach.
- One entry can only have one previous form to prevent the diamond problem (cyclic dependency).
Data Entry Behavior
- Data for the current form can only be added in the context of a previous form’s data.
- The previous entry’s ID is mandatory to save the current form’s data.
Route for Adding Data
/form/<current-form-id>/prev?entryId=<id-of-previous-data>
You can also use parameters to identify the previous entry dynamically:
/form/<current-form-id>/prev?$.ic=901021...
Dataset & UI Behavior
Dataset of a next form included in the current form automatically links using $prev$.$id = $.$id and filters by the prev data ID.
If the dataset requires additional parameters, "$prev$.$id": $.$id must be explicitly added in source init parameters.
1.3 Facets
Overview
A Facet controls the state of fields (edit, view, disabled, hidden, none).
Usage & Scripts
- You can open a form with a facet by passing the facet key in the URL:
/form/<form-id>/<facet-key>?entryId=<entryId> - In your scripts, you can check the current facet state using the
$action$variable.
1.4 Extended Form
Overview
An Extended Form inherits all items from the original form but allows you to rearrange, add, or remove items.
- Use Facet when: Differences are only in field states or minor script/validation variations.
- Use Extended Form when: The form structure/layout changes entirely or requires significantly different lifecycle/validation scripts.
1.5 Form Lifecycle & Items Control
A form provides several lifecycle events where you can run custom scripts. For multiline statements, always wrap the code in an IIFE (Immediately Invoked Function Expression).
| Lifecycle | Trigger | Description |
|---|---|---|
| Init Function | onInit() |
Runs on load. |
| On Save | onSave() |
Runs after entry data is saved. |
| On Submit | onSubmit() |
Runs after the entry data is submitted. |
| On View | onView() |
Runs when the entry is opened in view mode. |
Example: Reusing Init code in On View
(function(){
$this$.isView = true;
onInit(); // Call function directly to trigger outside of lifecycle
})()
Items Control (Field Behaviours)
- Post-action: Triggered automatically when the field value changes.
- Pre-requisite: Runs continuously on "ticks". It must return a truthy or falsy value to determine if the field is included/visible.
1.6 Pre-requisite
To get a value from a Normal Section as a pre-requisite value in a Child Section:
$_.data.mod_staf.code == "PA"
1.7 Evaluated Fields (EF) & Bindings
- Bindings: Evaluated in real-time on the client-side and run on continuous "ticks".
- Evaluated Fields (EF): The value for an EF is whatever is returned by the expression. Like lifecycle scripts, use an IIFE for multiline statements, and it must return a value.
- PDF Exports: Use
html-keepvaluein your markup if the evaluated value is needed during a PDF export. - Backend-EF (B-EF): Use B-EF to update prior data based on a newly evaluated field on the server side.
2. Dataset
2.1 Custom Query Builder
The Custom Query Builder allows you to define advanced, nested conditions for dataset queries using JSON. This gives you more flexibility than simple parameters.
- The outermost condition is controlled by
@cond(default: AND). - You can combine conditions using
$andand$or, or by specifying parameter keys directly.
Steps to Add a Custom Query Builder
- Navigate to UI Editor > Datasets.
- Select the dataset you want to edit.
- Click the Edit Dataset button.
- In the Edit Dataset modal dialog, go to the Filters tab.
- Under Custom Query Builder, enter your query JSON.
- Click Save List.
Query Builder Rules
- Keys can be:
$and→ logical AND (accepts an array of conditions)$or→ logical OR (accepts an array of conditions)- A parameter key (e.g.,
$.name~contain)
- Parameter keys in the query builder must match the dataset parameters, including decorators.
- Each condition (
$and,$or, or parameter) must be wrapped in its own object. - Outermost clause, value of
$andand value for$ormust be an array.
Example #1: Query Builder
[
{
"$and": [
{ "$.age~between": "" },
{ "$.gender.code": "M" }
]
},
{
"$or": [
{ "$.email": "{{$user$.email}}" },
{ "$_.email": "{{$user$.email}}" }
]
}
]
Parameter Value Resolution
In the Query Builder, a property’s value is only used if no parameter value or preset filter value is provided. If you know a parameter will always be supplied (via request or preset filter), you can safely set its value in the Query Builder to "" (empty string) or null.
Example #2: Passing values via HTTP request
?datasetId=222&$.age~between=12,50
(No need to pass $.gender.code, $.email, or $_email if already defined in the Custom Query Builder).
Example #3: Passing values via source init or _entry.dataset
{
"$.age~between": "12,50"
}
2.2 Decorator Reference
Parameter Decorators modify how a query checks a field. Below is the mapping of field types to their available decorators.
| Field type | Available decorators |
|---|---|
| Lookup | ~in, ~notin, ~contain, ~notcontain, ~from, ~to, ~between |
| Date, Number, Scale, ScaleTo5, ScaleTo10 | ~from, ~to, ~between |
| Text | ~in, ~notin, ~contain, ~notcontain |
Parameter Decorators
| Decorator | Description | Example | Result |
|---|---|---|---|
~in |
Field value is in provided list | $.country.code~in="ID,MY,PH,SG" |
Country is one of ID, MY, PH, SG |
~notin |
Field value not in list | $.country.code~notin="ID,MY,PH,SG" |
Country is not ID, MY, PH, SG |
~contain |
Field value contains string | $.name~contain="Mohd" |
Name contains "Mohd" |
~notcontain |
Field value does not contain string | $.name~notcontain="Bill" |
Name does not contain "Bill" |
~from |
Field value ≥ given number | $.age~from=12 |
Age ≥ 12 |
~to |
Field value ≤ given number | $.age~to=50 |
Age ≤ 50 |
~between |
Field value between two numbers | $.age~between="12,50" |
Age between 12 and 50 |
Special Parameter Values
| Value | Description | Example | Result |
|---|---|---|---|
~null |
Field value is NULL | $.gender="~null" |
Gender is null |
~notnull |
Field value is not NULL | $.gender="~notnull" |
Gender is not null |
$now$ |
Current timestamp | $.timestamp~to="$now$" |
Entry timestamp ≤ now |
$todayStart$ |
Today at 00:00 | $.timestamp~to="$todayStart$" |
Entry timestamp ≤ today start |
$todayEnd$ |
Today at 23:59:59 | $.timestamp~to="$todayEnd$" |
Entry timestamp ≤ today end |
Filters configured via Edit Dataset → Filters do not include decorators by default (except for numeric fields). If a decorator is required, you can manually edit the key in the Preset Conditions section to add the appropriate decorator.
2.3 Intersection Query
The ~in operator handles array/list intersections. This is particularly useful when querying child collections or repeating fields. It allows you to match records that contain at least one overlapping value within a list or multi-valued field.
Example Data:
Entry 1: { "data": { "categories": [ { "code": "A" }, { "code": "B" } ] } }
Entry 2: { "data": { "categories": [ { "code": "B" } ] } }
Entry 3: { "data": { "categories": [ { "code": "A" }, { "code": "C" } ] } }
Entry 4: { "data": { "categories": [ { "code": "B" }, { "code": "C" } ] } }
Query:
$.categories*.code~in=A,C
Query Explanation:
$.categories*Iterates over all elements in the categories list..codeTargets the code field of each category.~in=A,CMatches entries where any code value intersects with the set {A, C}.
Result:
The query returns entries whose categories list contains at least one matching code (A or C):
- ✓ Entry 1 (A, B)
- ✗ Entry 2 (B)
- ✓ Entry 3 (A, C)
- ✓ Entry 4 (B, C)
2.4 Filters, Preset Filters & Parameters
- Precedence if conflict:
Parameter > Preset Filter > List Filter - To structure a complex query, use the custom query builder.
Example:
[
{
"$or": [
{ "$.members*.email": "" },
{ "$.secretariat*.email": "" }
]
},
{
"$.status": "active"
}
]
2.5 Bulk Operations
Handling Selected Entries with $selected$:
When configuring a custom bulk action for a dataset, you can access the $selected$ object, which contains all the entries explicitly selected by the user in the UI.
The $selected$ object is structured as a dictionary (key-value mapping) where the key is the entry ID and the value is the entry data wrapper:
{
'652010': { id: 652010, data: { /* data object */ } },
'652011': { id: 652011, data: { /* data object */ } },
'652018': { id: 652018, data: { /* data object */ } }
}
Example 1: Update all selected entries
To update a specific field (e.g., setting selesai to true) for all selected entries, iterate through the object keys and use the $update$ function.
(function(){
Object.keys($selected$).forEach(id => {
$update$(id, { selesai: true });
});
})()
Example 2: Conditionally update selected entries
If you need to check a value before updating (e.g., only update if type is 'pelajar'), iterate through the object values to access the inner data payload.
(function(){
Object.values($selected$).forEach(entry => {
// Only update if the type is 'pelajar'
if (entry.data?.type == 'pelajar') {
$update$(entry.id, { selesai: true });
}
});
})()
2.6 Dataset Endpoints & Query Syntax
You can query dataset endpoints directly via URL parameters.
- Standard Query: Add parameters using the usual
$.field-code.
.../list?datasetId=1168&$.city.code=KCH - Range Queries: Use decorators for number/date/scale.
.../list?datasetId=1168&$.age~between=10,16 - Array/Child Queries: Use
*to query within multiple options.
.../list?datasetId=116&$.joblist*.company=SACOFA - Permissive Query (OR): By default, query params are restrictive (AND). Add
@cond=ORfor any-match.
.../list?datasetId=116&$.type.code=Stud&$.company=SACOFA&@cond=OR - Sorting: Use the
sortsparameter.
.../list?datasetId=116&sorts=$.birthdate~desc,$.name~asc
3. Dashboard
3.1 Advanced Charting: Multi-Category vs. Multi-Value
Understanding the distinction between configurations will help you choose the right visualization.
- Multi-Category Charts: Segments a single numerical metric by two or more descriptive attributes (e.g., clustered groupings in Bar charts, multi-pie grids in Pie charts). Drill-Down is disabled.
- Multi-Value Charts: Tracks multiple distinct numerical calculations against a single category axis (e.g., plotting Total Revenue vs Operating Costs on a Dual Y-Axis). Drill-Down is disabled.
If your primary goal is to allow users to click into a chart and view the underlying raw data (Drill-Down), stick to a Standard Chart (one category, one value).
3.2 Understanding Axes and Series
- X-Axis (xAxis): The horizontal axis (Categories).
- Y-Axis (yAxis): The vertical axis (Values).
- Series: The actual data plotted (bars, lines, pie slices).
3.3 Customizing Charts with ECharts Options
Add native ECharts options in Options > Additional options for chart. REKA will merge (and overwrite) your provided options with the defaults.
Example: Adding a DataZoom Scrollbar
{
"series": [{ "name": "Bilangan Peserta" }],
"dataZoom": [
{ "type": "inside", "start": 50, "end": 100 },
{ "show": true, "type": "slider", "y": "90%", "start": 50, "end": 100 }
]
}
3.4 Transforming Chart Data
You can modify datasets before rendering using Options > Transform Function.
For quick category or value mapping, use the built-in $eachName$ and $eachValue$ shortcuts:
- Rename categories:
$eachName$(i => 'Zone ' + i) - Transform values:
$eachValue$(i => i * 5)
Full Script Transformation:
Data for multi-value/category charts arrives as a multi-dimensional array (matrix). Ensure your script iterates rows and columns appropriately.
(function(){
let remapData = [...$dataset$];
if (remapData.length > 0) {
// 1. Fix header row
remapData[0] = remapData[0].map(h => h === 'n/a' ? "No Data" : h);
// 2. Fix category column
for (let i = 1; i < remapData.length; i++) {
if (remapData[i][0] === 'n/a') remapData[i][0] = "No Data";
}
}
return remapData;
})()
3.5 Restful Source Charts
Charts can be generated using data from restful endpoints instead of standard datasets. Ensure the endpoint returns data in the correct JSON array structure expected by the charting engine.
3.6 Enable Drill-Down List
To enable drill-down capabilities for a chart:
- Go to Options > Enable Drill-down.
- Select Columns: Choose the columns to display (limited to fields from a normal section).
- View Entry Button: Check 'Enable Drill-down View Entry' to allow users to open the full record.
Drill-down will not work for Multi-category or Multi-value charts, as these visualize aggregated data intersections rather than a single database row.
3.7 Chart Parameters & Decorators
Just like Datasets, Charts in REKA also support the use of decorators (~decorator) in their parameters to dynamically filter the underlying data before it is visualized.
This means you can apply the exact same parameter decorators—such as ~in, ~notin, ~contain, ~from, ~to, and ~between—directly to a chart's data source query.
Example Usage:
If you want a chart to only render data for specific categories (e.g., filtering a chart to only show the IT and HR departments), you can pass a parameter to the chart like so:
$.department~in=IT,HR
For a complete list of available decorators and how they function, please refer back to the 2.2 Decorator Reference in the Dataset section.
4. Lambda & Real-time in REKA
4.1 Overview
Lambda is a script runner in REKA that executes on the backend using JavaScript and polyglot Java API access.
- Lambdas execute on separate threads, making them ideal for long-running processes.
- A Lambda can only access data within its own app.
4.2 Development & Default Objects
Each Lambda automatically provides access to the following objects:
| Object | Description |
|---|---|
_request |
Represents the HTTP request object. |
_response |
Represents the HTTP response object. |
_out |
Used for building JSON responses. Example: _out.put("key", value); |
_param |
Provides access to request parameters. |
Always prefer _param instead of _request.getParameter(). _param works consistently whether the Lambda is triggered by a standard HTTP request or by a Cogna function call.
Handling Request Bodies
To get the raw request body in a Lambda (such as from a POST request), use _param._body. This will return a string. To convert it into a usable JSON object, you should parse it:
var requestData = JSON.parse(_param._body);
Available Endpoints generated by Lambda
| Endpoint Type | Description |
|---|---|
| Endpoint | Returns JSON (_out.put(key, value)) |
| Print / Print PDF | Returns text/PDF from print() |
| Stream | Streaming output for long-running processes |
| Web Viewer | Opens output in UI viewer. |
4.3 Common Use Cases for Lambda
- Scheduled Jobs: Run tasks automatically (cron-like).
- API Integrations: Use
_http.GETand_http.POST. - Data Validation: Run custom rules before entry saves.
- Cogna Integration: Register Lambda as an AI tool.
4.4 Web Scraping with Lambda (Jsoup)
Use the _jsoup binding for web scraping and HTML parsing. It provides DOM traversal using CSS selectors natively on the backend.
var doc = _jsoup.connect("https://en.wikipedia.org/").get();
doc.select("#mp-itn b a").forEach(h => print(h.text()));
5. Real-time Notification
REKA supports multiplexed connections using WebSockets to establish real-time pub/sub communication between clients.
5.1 Client-Side (UI) Usage
- Available in both Forms and Custom Screens.
- Subscribe:
$live$.watch('channel-name', callback) - Broadcast:
$live$.publish('channel-name', payload)
Ensure that your channel is unique to prevent unintended conflicts with other applications or environments. It is highly advisable to include the App ID in the channel key (e.g., channel_update_${$app$.id}).
5.2 Backend (Lambda) Usage
$live$ is also available in Lambda using the _live object. But first, you have to include Live in the Lambda Bindings configuration.
Then, use _live.publish to publish a live notification from Lambda to the listening client (usually a form or screen using $live$).
Lambda Script Example:
// ensure to stringify the message before publish.
_live.publish(['updated-ticket-info-' + entryId], JSON.stringify(updatedTicket));
Client Listener Example:
On the listening client, parse it back to an object using JSON.parse().
$live$.watch(['updated-ticket-info-' + $.$id], res => {
let parseObj = JSON.parse(res);
// Assign to local variable or scope
$_ = parseObj;
});
6. Integrations & Endpoints
6.1 Enabling a Custom Domain
You can use a reverse proxy to route traffic from a custom domain (e.g., app.example.com) to your REKA subdomain app-path.ireka.my.
Apache (.htaccess)
Requires mod_proxy and mod_headers.
<IfModule mod_rewrite.c>
RewriteEngine On
# Forward the original host expected by the Reka platform
<IfModule mod_headers.c>
RequestHeader set Host "app-path.ireka.my"
</IfModule>
# Reverse proxy all requests to the Reka application
RewriteRule ^(.*)$ https://app-path.ireka.my/$1 [P,L]
</IfModule>
Nginx
Use proxy_pass and proxy_set_header Host in your server block.
server {
listen 443 ssl;
server_name mydomain.com;
location / {
proxy_pass https://app-path.ireka.my/;
proxy_set_header Host app-path.ireka.my;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_ssl_server_name on;
}
}
6.2 Telegram Bot Setup x Reka
Use @BotFather on Telegram.
- Run
/newbot - Set the Name and unique Username (must end in
bot). - Obtain the token format
<bot_id>:<secret_token>for webhooks.
6.3 Integrating REKA into Mobile Apps (WebView)
Embed specific components (Forms/Dashboards) via native WebView wrappers.
Requirements
Enable the following on your mobile WebView client:
- File Upload: Needed for attachments.
- Camera Access: Needed for capture fields.
- Geolocation: Needed for location fields.
- Service Workers: Needed for PWA/offline caching.
Authentication
Append tokens to the URL parameters to authenticate the WebView session natively:
?accessToken=X&provider=Y?apiKey=Z(For system/kiosk level access)
Android (WebView) Example
WebView webView = findViewById(R.id.webview);
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
settings.setAllowFileAccess(true);
settings.setAllowContentAccess(true);
settings.setMediaPlaybackRequiresUserGesture(false);
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("https://hr-system.ireka.my/?apiKey=abc123xyz");
iOS (WKWebView) Example
let config = WKWebViewConfiguration()
config.preferences.javaScriptEnabled = true
config.websiteDataStore = .default()
let webView = WKWebView(frame: view.bounds, configuration: config)
view.addSubview(webView)
let url = URL(string: "https://hr-system.ireka.my/?accessToken=XXXX&provider=google")!
webView.load(URLRequest(url: url))
6.4 3rd Party Integration Methods
- Backend Data (Inbound/Outbound): Achieved via Restful API using
$http$,$endpoint$, or custom Lambda functions. - Frontend Library Integration: External JS libraries can be injected directly into forms/screens using the
$loadjs$utility. - Tooling (Reporting/Analytics): Can consume data from dataset endpoints, chart endpoints, or custom Lambdas.
6.5 External Endpoints Manager
Use the Endpoint Manager to register and securely manage external API endpoints centrally.
- Authentication: Native support for OAuth2 flows.
- Execution: Can be called via
$endpoint$on the frontend or_endpointin Lambda. - Parameters: URL parameters can be unboxed dynamically using placeholders
{}populated by a provided JSON object payload.
File Blob / Byte Array Handling
If an external endpoint returns a file (blob), set the configuration to Response Type: Byte Array to prevent file corruption.
- Frontend: Convert the byte array to a file object using
blob:base64. - Lambda: Write the byte array directly to the response output stream:
var out = _response.getOutputStream();
out.write(byteArray);
7. Lookups
7.1 Database vs Restful Lookups
REKA allows fields to pull data from either internal Database Lookups or external Restful API Lookups. Each requires specific configurations for data mapping.
Restful Lookup Configuration
- Endpoint URL: Supports placeholders
{}that are dynamically unboxed with values passed via parameters. - Root: Points to the specific JSON path that contains the array or list of data to be iterated.
- Code, Name, Extra: Points to the specific JSON paths for these respective values (this path should be relative to, or excluding, the Root path).
Additional Data Fields
How additional data is handled depends on the type of lookup being used:
Lookup-Database:
- You must specify additional fields as a schema.
- To specify the data type, use the format:
field_name:type - Supported types:
text,longtext,number,date,file,options,lookup.
Lookup-Restful:
- You can leave the schema configuration blank to automatically include all remaining JSON fields as additional data.
- To explicitly remap, rename, or flatten deep JSON fields, use the
@syntax.
General Syntax to Map Fields
Whether remapping a Restful lookup or structuring a Database lookup, use the following general syntax:
field_name:type@/path/to/value
7.2 Lookup Query Endpoints
You can pass parameters directly into Lookup Query Endpoints to filter lists.
- Database Lookup:
.../lookup/5108/entry?extra=Staff&$.gender=Male(Can be filtered using Code, Name, Extra, or$.<additional-field>). - Restful Lookup: Only supports parameters specifically supported by the source API endpoint.
If a Restful lookup requires a POST request with parameters in the body, pass a postBody array literal:
{
"postBody": [{"paramName": "co_id", "paramValue": $.cp_course_id.extra}]
}
8. REKA Templating & Screens
8.1 Formatting Pipes
REKA provides formatting pipes ({{val|pipe}}) to transform data directly on the view before rendering.
| Pipe Usage | Description / Format |
|---|---|
{{$.date_field|date:"DD-MM-YYYY"}} |
Custom Date string formatting. |
{{$.attachment|src:inline}} |
Inline display (Streamable video/audio: src:stream) |
{{$.filing_no|qr}} |
Generates base64 QR Code image source. |
{{$.amount|number:"1.2-3"}} |
Number format: minInt.minFrac-maxFrac |
8.2 Mailer Templating
The Mailer module uses StringTemplate (ST) v4 engine. It supports array iteration ({{ $.userlist:{user | ...} }}) and conditional logic ({{if (...)}} ... {{endif}}).
Field Formatters (Inline Transformations)
| Formatter syntax | Description |
|---|---|
{{$.date;format="date:dd/MM/yyyy HH:mm"}} |
Date formatter |
{{$.number;format="number:%32.12f"}} |
Number formatter (Uses Java String Formatter) |
{{$.text;format="string:upper"}} |
Make uppercase |
{{$.text;format="string:lower"}} |
Make lowercase |
{{$.text;format="string:cap"}} |
Make first-cap |
{{$.text;format="string:url-encode"}} |
Encode URL |
{{$.text;format="string:xml-encode"}} |
Encode XML |
{{$.file;format="src"}} |
Upload file URL |
{{$.file;format="qr"}} |
QR image src |
Triggering Mailer via Lambda
// Direct Payload formulation
_mail.send({ to: "...", subject: "...", content: "..." }, _this);
// Pre-defined Template mapping
_mail.sendWithTemplate("mailer-id", entry_data, _this);
8.3 Custom Screens
Custom screens allow you to build completely bespoke interfaces inside the REKA app shell wrapper.
- Capabilities: Supports native plugins like the QR scanner integration.
- Scripting Scope: Logic can be scoped to the Entry Page context, Entry List, or global Static Page contexts depending on the screen type selected.
9. App Structure & Global Variables
9.1 Global $conf$ Object
$conf$ is a state object used to declare app-scoped global variables that persist throughout the user session.
- The values stored in
$conf$are accessible across all components, such as forms, datasets, and custom screens. - To initialize and declare values for
$conf$immediately when the app starts, place your logic inside the Structure Init Function.
// Example in Structure Init
$conf$.deptCode = "HR_01";
Async Initialization & Change Detection
The App Structure Init function also supports asynchronous operations. This is highly useful when you need to fetch global data (like user profiles or lookup dictionaries) via API before rendering dependent UI components.
Example:
(async function(){
let profileRes = await $web$.get('https://io.ireka.my/api/entry/by-params?formId=5473', {
params:{
'$.email': $user$.email
}
});
$conf$.profile = profileRes.data;
$digest$();
})()
- Note the keyword
asyncin the IIFE (Immediately Invoked Function Expression) and the use ofawaitfor the$web$.getrequest. - If the value of
$conf$.profile(or any asynchronously fetched global variable) is used directly in the UI template, it is a good idea to call$digest$()after setting the value to ensure the change detection is fired up and the interface updates immediately.