Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: improved explanation about using config values; added section on validators

...

import { defineConfigSchema, validators } from "@openmrs/esm-module-config"

defineConfigSchema("@openmrs/esm-hologram-doctor", { hologram: { color: { default: false,
validators: [validators.isBoolean] } }, virtualProvider: { name: { family: { default: "Kenobi",
validators: [
validators.isString,
validator(n => n != "Vader", "cannot be a vader")
] } } } })

Validators

You should provide validators for your configuration elements wherever possible. This reduces the probability that implementers using your module will have hard-to-debug runtime errors. It gives you, the module developer, the opportunity to provide implementers with very helpful explanations about why their configuration won't work.

robot: {
  name: {
    default: "R2D2",
    validators: [
      validators.isString,
      validator(n => /\d/.test(n), "all robots must have numbers in their names")
    ]
  }
}

A validator can be created using the validator function. The first argument is a function that takes the config value as its only argument. If the function returns something truthy, validation passes. If the function returns something falsy, an error is thrown with the second argument as an explanation.

For convenience, some common validators are provided out of the box. These are

  • isBoolean
  • isString

Using config values

The generic way

The config is fetched asynchronously using getConfig(moduleName). Continuing the above example, we would have something like

import { getConfig } from "@openmrs/esm-module-config"
                                                       
async function doctorGreeting() {     
  const config = await getConfig("@openmrs/esm-hologram-doctor")
  return "Hello, my name is Dr. " + config.virtualProvider.name.family
}

The content of config will be pulled from the config files, falling back to the defaults for configuration elements for which no values have been provided.

...

React support

A React Hook is provided to hide the asynchronicity of config loading. The moduleName provided to the openmrsRootDecorator is used to look up the configuration elsewhere in the application. So in the example above, the root decorator call would look something like

export default openmrsRootDecorator({
  featureName: "hologram doctor",
  moduleName: "@openmrs/esm-hologram-doctor"
})(Root)

...

import { useConfig } from "@openmrs/esm-module-config"
                                             

        
export default function DoctorGreeting() {     
  const config = useConfig()
  const greeting = "Hello, my name is Dr. " + config.virtualProvider.name.family
  return (
    <div>{ greeting }</div>
  )
}

The content of config will be pulled from the config files, falling back to the defaults for configuration elements for which no values have been provided.

...

Support in other frameworks (Angular, Vue, Svelte,

...

etc.)

This hasn't been implemented yet, but we would like to implement it! Please reach out to bistenes@pih.org and/or open an issue on the OpenMRS Jira.

...