The chances are highly likely for you to run into scenarios where there will be repetitive code in your solutions.
And althought we at Jigx are constantly looking at ways to make things easier for you, there’s already some tips and tricks you can use to elevate your development and save some time.
In this post I will be discussing three areas where slight improvements could save you a great deal of effort:
- Using global vs local datasources
- Using global actions for repetitive actions
- Using expressions for repetitive conditional checks, etc.
Let’s get started, shall we?
1. Global vs Local Datasources
The first suggestion probably seems like a bit of a non-brainer, yet this one regularly makes an appearance. A good general rule-of-thumb is to use global datasources as much as possible unless you are unable to. This allows you to merely reference the table everywhere in your solution, but prevents you from having to define the datasource locally everywhere you use it.
Local datasources should be used only in instances where you want to pass in parameters for your query that are only available on a particular jig.
For example if you want to filter records on a list, the filter value is defined in that jig and so your query would happen on the jig itself.
2. Global Actions
More often-than-not, I’ve run into scenarios where the same actions are used in various places, often with just a tiny bit of a difference between them. You may find that setting up a global action to dynamically handle these differences may save you lots of time (and space) too.
Take this code for example, the actions are very similar and as a result can easily be moved over to a global action. Notice the code difference when you move them over to a global action using the action.execute-action
. Commented out code is the previous actions and the current actions under onPress are where I’m reusing the same global action called expander-action
:
type: component.expander
instanceId: process-info
options:
isInitiallyCollapsed: false
header:
centerElement:
type: component.titles
options:
title: =@ctx.current.item.question
subtitle: |
=@ctx.components.chkYes.state.value = true ? 'Yes':
@ctx.components.chkNo.state.value = true ? 'No':
@ctx.components.chkNA.state.value = true ? "N/A": " "
icon: |
=@ctx.components.chkYes.state.value = true ? 'checkbox-checked':
@ctx.components.chkNo.state.value = true ? 'checkbox-checked':
@ctx.components.chkNA.state.value = true ? 'checkbox-checked':'checkbox-unchecked'
iconColor: |
=@ctx.components.chkYes.state.value = true ? 'positive':
@ctx.components.chkNo.state.value = true ? 'negative':
@ctx.components.chkNA.state.value = true ? 'color3':'color14'
children:
- type: component.entity
options:
children:
- type: component.entity-field
options:
label: Question
value: =@ctx.current.item.question & '?'
- type: component.entity
options:
children:
- type: component.entity-field
options:
label: Description
value: =@ctx.current.item.description
- type: component.form
options:
isDiscardChangesAlertEnabled: false
children:
- type: component.field-row
options:
children:
- type: component.checkbox
instanceId: chkYes
options:
isRequired: false
isOptionalLabelHidden: true
label: Yes
style:
isDisabled: =@ctx.components.chkYes.state.value
onPress:
type: action.execute-action
options:
action: expander-action
parameters:
when: =@ctx.components.chkNo.state.value
count: =@ctx.datasources.summaryCount.count - 1
# type: action.action-list
# options:
# actions:
# - type: action.execute-entity
# when: =@ctx.components.chkNo.state.value
# options:
# provider: DATA_PROVIDER_LOCAL
# entity: summaryCount
# method: save
# goBack: stay
# data:
# id: ='CK/Process-' & @ctx.solution.state.summaryId
# title:
# count: =$count(@ctx.datasources.summaryCount.count) - 1
# - type: action.reset-state
# options:
# state: =@ctx.components.chkNo.state.value
- type: component.checkbox
instanceId: chkNo
options:
isRequired: false
isOptionalLabelHidden: true
label: No
style:
isDisabled: =@ctx.components.chkNo.state.value
onPress:
type: action.execute-action
options:
action: expander-action
parameters:
when: =@ctx.components.chkYes.state.value
count: =$count(@ctx.datasources.summaryCount.count) < 1 ? 1:$number(@ctx.datasources.summaryCount.count) + 1
reset: =@ctx.components.chkNA.state.value
# type: action.action-list
# options:
# actions:
# - type: action.execute-entity
# when: =@ctx.components.chkYes.state.value
# options:
# provider: DATA_PROVIDER_LOCAL
# entity: summaryCount
# method: save
# goBack: stay
# data:
# id: ='CK/Process-' & @ctx.solution.state.summaryId
# count: =$count(@ctx.datasources.summaryCount.count) < 1 ? 1:$number(@ctx.datasources.summaryCount.count) + 1
# - type: action.reset-state
# options:
# state: =@ctx.components.chkYes.state.value
# - type: action.reset-state
# options:
# state: =@ctx.components.chkNA.state.value
- type: component.checkbox
instanceId: chkNA
options:
isRequired: false
isOptionalLabelHidden: true
label: N/A
style:
isDisabled: =@ctx.components.chkNA.state.value
onPress:
type: action.execute-action
options:
action: expander-action
parameters:
when: =@ctx.components.chkYes.state.value
count: =@ctx.datasources.summaryCount.count - 1
reset: =@ctx.components.chkNA.state.value
Here is the action definition:
action:
type: action.action-list
options:
actions:
- type: action.execute-entity
when: =@ctx.action.parameters.when
options:
provider: DATA_PROVIDER_LOCAL
entity: summaryCount
method: save
goBack: stay
data:
id: ='CK/Process-' & @ctx.solution.state.summaryId
title:
count: =ctx.action.parameters.count
- type: action.reset-state
options:
state: =@ctx.action.parameters.when
- type: action.reset-state
when: =@ctx.action.parameters.reset != null
options:
state: =@ctx.action.parameters.reset
parameters:
when:
type: string
required: true
reset:
type: string
required: false
count:
type: number
required: true
Other than re-usability, this provides you with only one place that you may need to update certain fields that need to be changed instead of having to change this in multiple places.
3. Expressions
Expressions are useful to break down complex queries or even aid as a tool to add reusability in a simple way. Expressions can be either local (set up in the jig) or global (set up in the index file).
Using the above example, I’d like to provide some examples for you of how expressions can be used to:
i.) Improve reusability
ii.) Improve code length by using shorthand instead of full expressions
iii.) Improve time spent when updates are required as you only need to manage that in the expressions and not everywhere the expressions are called.
Look at the below code as an example and compare it to the original code above.
Notice that the value of chkYes
is now only managed in the expressions.
Should you need to update the instanceId of the component, you only need to update it one place.
Examples that rely on solution.state or other environmental or solution level variables are easy to set up in your global expressions.
type: component.expander
instanceId: process-info
options:
isInitiallyCollapsed: false
header:
centerElement:
type: component.titles
options:
title: =@ctx.current.item.question
subtitle: |
=$chkYesValue ? 'Yes':
$chkNoValue = true ? 'No':
$chkNaValue = true ? "N/A": " "
icon: |
=$chkYesValue = true ? 'checkbox-checked':
$chkNoValue = true ? 'checkbox-checked':
$chkNaValue = true ? 'checkbox-checked':'checkbox-unchecked'
iconColor: |
=$chkYesValue = true ? 'positive':
$chkNoValue = true ? 'negative':
$chkNaValue = true ? 'color3':'color14'
children:
- type: component.entity
options:
children:
- type: component.entity-field
options:
label: Question
value: =@ctx.current.item.question & '?'
- type: component.entity
options:
children:
- type: component.entity-field
options:
label: Description
value: =@ctx.current.item.description
- type: component.form
options:
isDiscardChangesAlertEnabled: false
children:
- type: component.field-row
options:
children:
- type: component.checkbox
instanceId: chkYes
options:
isRequired: false
isOptionalLabelHidden: true
label: Yes
style:
isDisabled: =$chkYesValue
onPress:
type: action.execute-action
options:
action: expander-action
parameters:
when: =$chkNoValue
count: =$countDatasource - 1
- type: component.checkbox
instanceId: chkNo
options:
isRequired: false
isOptionalLabelHidden: true
label: No
style:
isDisabled: =$chkNoValue
onPress:
type: action.execute-action
options:
action: expander-action
parameters:
when: =$chkYesValue
count: =$countDatasource < 1 ? 1:$number$countDatasource) + 1
reset: =$chkYesValue
- type: component.checkbox
instanceId: chkNA
options:
isRequired: false
isOptionalLabelHidden: true
label: N/A
style:
isDisabled: =$chkNaValue
onPress:
type: action.execute-action
options:
action: expander-action
parameters:
when: =$chkYesValue
count: =$countDatasource - 1
reset: =$chkYesValue
expressions:
# Can be referenced by full expression @ctx.expressions.{key} or using the shorthand ${key}
chkNaValue: =@ctx.components.chkNA.state.value
chkNoValue: =@ctx.components.chkNo.state.value
chkYesValue: =@ctx.components.chkYes.state.value
countDatasource: =@ctx.datasources.summaryCount.count