VA Forms Library - How to work with Array Data (aka List Loops)
When working with form data, it can make sense to keep associated data grouped together. This may be a military service history that includes multiple tours of duty, a list of dependents associated with a Veteran, or a collection of service related disabilities. Structurally, this data is represented as an array of objects in a given form’s formData
. Colloquially, some application teams, engineers, and designers may refer to this particular pattern as a “list loop.” This guide will walk through the configuration required to use array based data in a schema, uiSchema, and formConfig
.
List Loop
The term “list loop” originates from how the Forms Library visually presents array data. For example, if a Veteran is filling out information for a list of children, they would add the names of each child first, thereby creating a list (array data structure). Then, they would traverse through all pages for child one and enter data, before “looping back” to fill out the same data for child two.
Schema Configuration
Page One
export const someSchema = {
type: 'object',
properties: {
someArrayProperty: {
type: 'array',
minItems: 1,
items: {
type: 'object',
properties: {
first: {},
middle: {},
last: {},
},
},
},
},
};
Working with array data starts with configuring a schema property that is typed as an array. In the example above, the someArrayProperty
property is initialized as an array and it includes an items
property. The items
property represents what individual indexed entries in the array will contain. In this case, items
houses biographical data.
Lists Only
Schema configuration for array data could end here and that would be okay. Visually, all array entries would be displayed on one form page and there would be no “looping” aspect to fill out data for each entry.
Page Two
export const someOtherSchema = {
type: 'object',
properties: {
someArrayProperty: {
type: 'array',
minItems: 1,
items: {
type: 'object',
properties: {
country: ""
state: "",
street: "",
city: "",
postal: "",
},
},
},
},
};
Creating a second page for array based data to traverse through, thereby creating the list loop pattern, is practically identical to the first page. An array typed schema property is initialized with the same property name as the array property in page one. This lets react-jsonschema-form know that this data is associated. Form state and object merging is handled internal to react-jsonschema-form. In this instance, the second page of our list loop contains address data for each entry created on page one.
uiSchema Configuration
There are no specific differences to uiSchema configuration when working with array based data. However, one thing to note when working with array data and uiSchema is that ui:required
provides an index
argument, useful for accessing data at a particular index in the array:
{
'ui:title': 'State',
'ui:required': (formData, index) =>
formData?.someArrayProperty[`${index}`]?.country ===
"USA",
},
formConfig Configuration
someChapter: {
pages: {
dependentName: {
title: 'Some title',
path: 'some-path',
uiSchema,
schema,
},
dependentPlaceOfBirth: {
title: 'Some title',
path: 'some-path/:index',
showPagePerItem: true,
arrayPath: 'someArrayProperty',
uiSchema,
schema,
},
dependentAdditionalInformation: {
title: 'Some title',
path: 'some-path/:index/additional-path-name',
showPagePerItem: true,
arrayPath: 'someArrayProperty',
uiSchema,
schema,
},
},
},
formConfig setup is similar to regular page configuration, with several additions worth mentioning:
Each page that follows the first page for array based data must include a property called
arrayPath
whose value is equal to the property name specified in the corresponding schema. In this example,someArrayProperty
.showPagePerItem
specifies that each item in an array will get turned into a distinct page.Each additional page needs a
path
property that includes the:index
parameter. This allows the forms library to keep track of associated data per index.
Examples in production
Form 686c-674 - contains an add child workflow that includes list loops
Help and feedback
Get help from the Platform Support Team in Slack.
Submit a feature idea to the Platform.