Occasionally, there may be a need to modify a form schema from the frontend instead of directly in vets-json-schema. This can be achieved through the use of two properties in uiSchema, updateSchema and replaceSchema. The primary difference between the two properties is that updateSchema merges new schema changes with the existing one, and replaceSchema totally removes and replaces existing schema properties.

In the regular update data flow process for Forms Library forms, both updateSchema and replaceSchema are handled by a single function called updateSchemaFromUiSchema.

Both updateSchema and replaceSchema accept the following parameters:

  • formData

  • schema

  • uiSchema

  • index - optional, provided if working with array data

  • path - optional, can contain the path, relative to formData, to the data corresponding to the current schema object

updateSchema

Useful for changing certain aspects of an underlying schema but maintaining the rest of it.

Example: Title change based on some other form data value using updateSchema

From the Burials form config:

updateSchema: formData => {
  let title;
  if (isVeteran(formData)) {
    title =
      'Is there anyone currently buried in a VA national cemetery under your eligibility?';
  } else {
    title =
      'Is there anyone currently buried in a VA national cemetery under your sponsor’s eligibility?';
  }
  return { title };
},
JS
Screenshot showing the form question text if a user has identified as a Veteran
Screenshot showing the form question text if  a user has identified as other than Veteran

Example: Changing properties in a schema

From the 10182 areaOfDisagreement uiSchema (uses this helper function):

updateSchema: (formData, _schema, _uiSchema, index) => ({
  type: 'string',
  maxLength: calculateOtherMaxLength(
    formData.areaOfDisagreement[index],
  ),
}),
JS
Screen shot showing the maximum description input length allowed when two check boxes are checked
Screen shot showing the maximum description input length allowed when three check boxes are checked
Screen shot showing the maximum description input length allowed when one check box is checked

replaceSchema

Useful for completely changing a schema. Note: a possible gotcha when using replaceSchema is that changing the type of a schema may cause validation to fail on form submission because vets-api uses the original schema in vets-json-schema for data validation. If schema types do not match, submission may return an error.

Example: Changing address fields if a user lives on a military base

From the profileAddress definition:

// Replacing the city text field with a select field if a user selects military base
replaceSchema: (formData, schema, uiSchema, index) => {
      const formDataPath = getPath(path, index);
      const { isMilitary } = get(formDataPath, formData) ?? {};
      if (isMilitary) {
        return {
          type: 'string',
          title: 'APO/FPO/DPO',
          enum: constants.militaryCities.map(city => city.value),
          enumNames: constants.militaryCities.map(city => city.label),
        };
      }
      return {
        type: 'string',
        title: 'City',
        minLength: 1,
        maxLength: 100,
        pattern: STREET_PATTERN,
      };
    },
  },
},

// Replacing the state field with different options depending on whether a user 
// lives on a military base, in the United States, or in a different country
replaceSchema: (formData, schema, uiSchema, index) => {
  const formDataPath = getPath(path, index);
  const { country, isMilitary } = get(formDataPath, formData) ?? {};
  if (isMilitary) {
    return {
      type: 'string',
      title: 'State',
      enum: constants.militaryStates.map(state => state.value),
      enumNames: constants.militaryStates.map(state => state.label),
    };
  }
  if (!isMilitary && country === 'USA') {
    return {
      type: 'string',
      title: 'State',
      enum: filteredStates.map(state => state.value),
      enumNames: filteredStates.map(state => state.label),
    };
  }
  return {
    type: 'string',
    title: 'State/Province/Region',
  };
},
JS
Animated Gif showing address field schemas updating based on other field values