State

Global application state and methods

Global application state and methods

Expressions

Expressions are a simple way to access data from the app runtime, or the response from server.
Data is accessed through an object that is internally known as Core context or Expression context.
If expression fails, it will return undefined. If you specify the default parameter, it will be returned when expression fails.

Examples of expressions:

property: !expression flow.export.value
property:
  !expression eval: flow.export.value
  default: Nothing
# Multiline expression
property:
  !expression: |
    const variable = 1;
    // More lines of JavaScript
    console.log('Hello', variable);

Functions

A function is another type of expression. It's useful to add some callbacks, such as a button onClick event.

- !component as: div
  onClick: !function "console.log('Click')"
  items: "Click me"

Extending Expression context

To extend expression context with custom values or methods, globals or utils configuration keys can be used:

# index.yml
globals:
  test: "I am a global variable"
utils:
  sum: !expression "function (a, b) { return a + b; }"

Then in page configuration:

- !component as: Heading
  items: !expression "globals.test"
- !component as: Heading
  items: !expression "utils.sum(1, 2)"

Expression context

Expression context is a global object, which is accessible from YAML expression only.

  • analytics - functions for trigger analytics events
analytics: {
  authorization: (token) => void, // Trigger mixpanel.identify(token), GA.set({ userId: token }) and GTM dataLayer event "authorization" with parameter token (string)
  event: (name: string, params?: object) => void, // Trigger event with given event name and params
  storage: { // More info in "Analytics storage" section
    set: (name: string, value: any) => void
    get: (name: string) => any
    increment: (name: string) => void
  }
}
  • api - information about API
api: {
  authToken: string,
  progress: {
    [field-name]: number // Percentage of progress in file uploading
  }
}
  • app - information about app
app: {
  locale: string, // Current locale
  targetId: string, // Current target name
  waiting: {
    [tag]: boolean, // App waiting tags
  }
  wrapByLoading: (promise: Promise<any>) => Promise<any>
}

Example usage of wrapByLoading

# Element with click handler as async operation
- !component as: div
  items: "Run simple async operation"
  onClick: !function "app.wrapByLoading(simple_async_operation, 'SIMPLE_TAG')"

# Element with click handler as async operation with complex structure
- !component as: div
  items: "Run complex async operation"
  onClick: !function |
    app.wrapByLoading((async () => {
      await complex_async_operation();
    })(), 'COMPLEX_TAG')

# Displaying loader during async operation
- !component as: VisibilityWrapper
  visible: !expression "app.waiting.SIMPLE_TAG || app.waiting.COMPLEX_TAG"
  items: "Loading..."
  • configuration - complete configuration of your target in json. This is an output from target-builder module, which parses all files inside target folder and produces large JSON that contains all settings, configurations, pages structures, etc.

  • constants - list of constants, the most important ones are: COUNTRIES_FULL, COUNTRIES, COUNTRY_CODES, LANGUAGES

  • cookie - methods exported from js-cookie module (cookie.get, cookie.set, cookie.remove)

  • cx - method exported from classnames module

  • device - information about device

device: {
  ... // https://github.com/duskload/react-device-detect#selectors
  hasWebcam: boolean, // If device has webcamera physically
  hasWebcamPermission: boolean, // If user already granted webcamera permission to current website
}
  • flow - data from server about flow and flow/route functions from server
flow: {
  backEnabled: boolean, // value of backEnabled from API for current page
  execution: { // information about current flow execution
    uuid: string
    token: string
  },
  export: ...any-data-from-server, // this is exported data for page in flow from server
  function: {
    [function-name]: (payload?: any, resultKey?: string) => void, // - call (in !fuction) any flow/route function by call function name (like `flow.function.search('something')`), you can also set output resultKey (default function-name)
    results: {
      [function-name or result-key]: ...any-data-from-server-function, // - here will be data from server under function-name or result-key property name (like `flow.function.results.search`)
    }
  }
  goToErrorPage: (message: string, logout?: boolean) => void // redirect user to error page (if one is specified) with some message put into `page.params.error`. Optionally logout can be performed
  refresh: () => void // refresh workflow based on current workflow status
  reload: () => void // removes authentication cookie and reloads flow
}
  • form - data about form, including states of fields
form: {
  changeValue: (fieldName: string, value: any, callback?: () => void) => void, // change value of some field, you can use callback that will be called after data set, for example if you need to submit form
  data: {
    [field-name]: ...data-inside-field, // - data can be string, file, etc.
  },
  field: {
    [field-name]: {
      isValid: boolean,           // is field valid
      validationError: string,    // only validation erros generated by page schema
      error: string,              // all field errors including validation errors and server errors
      isFilled: boolean,          // is there any data
      isVisited: boolean,         // true, if field was visited before (focused and blur)
    }
  },
  recompileSchema: () => void, // recompile form validation schema
  clearErrors: (allErrors?: boolean) => void // clear global/validation/manually set errors
  setError: (fieldName: string, error: string) => void // manually set error to some specific field, error can be cleared by passing falsy value
  addTags: (tags: string[]) => void, // add tags to form
  removeTags: (tags: string[]) => void, // regexp as string can be also used to identify more tags
  hasTags: (tags: string | string[]) => boolean // checks if all passed tags are present
  tag: {
    [tag-name]: boolean, // form visual tags
  },
  submit: (actionName: string, params: string[]) => void, // submit form
  valid: boolean, // is form valid
  visited: {
    [field-name]: boolean // indicated if field was visited
  },
}
  • format - global formats used in application
format: {
  formatDate: (date: string) => string
  formatCurrency: (value: number, options?: NumberFormat) => string
  formatNumber: (value: number, options?: NumberFormat) => string
  roundNumber: (value: number) => number
  dateFormat: string
  currencyUnit: string
  phoneCountryCode: string
  phoneMask: string
}
  • globals - custom constants/variables, see more on how to extend expression context

  • helper - Helper functions and 3rd party libraries

helper: {
  dayjs, // https://github.com/iamkun/dayjs
  getFileHolder: (file: File | Blob) => Promise<FileHolder> // Get FileHolder compatible with HUB client
}
  • locals - local page variables and functions
# page.yml
locals:
  test: "I am a local variable"
  sum: !expression "function (a, b) { return a + b; }"
items:
- !component as: Heading
  items: !expression "globals.test"
- !component as: Heading
  items: !expression "globals.sum(1, 2)"
  • page - parameters of page, which may be an error. This data is set only from the local application, not the server
page: {
  params: any // for example page.params.error contains informations, why you are on error page
  name: string // current page name (route URI)
  storage: { // local page storage, gets cleared on page change
    get: (name: string, defaultValue?: any) => any
    set: (name: string, value: any) => void
  }
}
  • translates - function to translate a string of text, change current locale
changeLocale: (locale: string) => void
t: (string, params) => string
te: (string, params) => string
  • url - information about locations, query params, etc.
url: {
  ... // - https://github.com/unshiftio/url-parse
}
  • utils - custom methods, see more on how to extend expression context