Skip to main content
Version: v6

Path concepts

While the id property can uniquely identify a rule or group, an id won't naturally indicate anything about the position of the object within the query hierarchy. For that reason, React Query Builder uses the concept of a "path" to locate and update query objects.

The path property is an array of integers unique to each rule and group within a query. The query object itself, aka the root group, has a path of []. All other rules and groups within the query have a path that corresponds to their position within the rules array(s) of their ancestor group(s).

The path of any object (rule or group) is equivalent to the path of its parent group plus another array element which is the index of the object within its parent's rules array. You can think of it like this: path = [...parentPath, index].

Consider the following query. The respective path for each rule and group is commented above it, along with a short explanation.

// [] (the root group)
const query: RuleGroupType = {
combinator: 'and',
rules: [
// [0] (the first, aka zeroth, element in the root rules array)
{ field: 'f1', operator: '=', value: 'v1' },
// [1] (the second element in the root rules array is a sub-group)
{
combinator: 'or',
rules: [
// [1, 0] (the first element within the rules array
// of the group occupying the second position
// in the root rules array)
{ field: 'f2', operator: '=', value: 'v2' },
// [1, 1] (the second element within the rules array
// of the group occupying the second position
// in the root rules array)
{ field: 'f3', operator: '=', value: 'v3' },
],
},
],
};

The path of the top-most rule in the query is [0], 0 being the index of that rule within the root group's rules array. The path of the first sub-group in the query is [1], again according to its index within the outermost rules array. Each child rule of that group has a path that begins with 1 (the path of its parent), followed by its own index.

Finding a path

Use the findPath function to locate a specific rule or group for examination or update. Given the query above:

findPath([1, 0], query);

would return this object:

{ "field": "f2", "operator": "=", "value": "v2" }

Example

In most scenarios you won't need to interact with the path attribute, but it can come in handy in certain situations. One such situation is if you need to access other parts of the query from within a custom component.

tip

By default, custom components only receive props relevant to the rule or group they act on, but you can augment these default props with other data or information by using the context prop.

Say you have a custom value editor that needs to know the value of each of its sibling rules. We would recommend passing the entire query down through the context prop and retrieving the sibling rules with a combination of getParentPath and findPath.

import {
  findPath,
  getParentPath,
  RuleGroupType,
  RuleType,
  ValueEditor,
  ValueEditorProps,
} from 'react-querybuilder';

export const CustomValueEditor = (props: ValueEditorProps) => {
  // Get the path of this rule's parent group
  const parentPath = getParentPath(props.path);
  // Find the parent group object in the query
  const parentGroup = findPath(parentPath, props.context.query) as RuleGroupType;
  const id = findPath(props.path, props.context.query)!.id;
  // Get a comma-separated list of all sibling rule values
  const siblingValues = (
    parentGroup.rules.filter(
      r =>
        // filter out groups
        !('rules' in r) &&
        // filter out self
        r.id !== id
    ) as RuleType[]
  )
    // map the `value` property
    .map(r => r.value)
    // join with comma
    .join(', ');

  return (
    <div style={{ display: 'flex', flexDirection: 'column' }}>
      <ValueEditor {...props} />
      <span>Others: {siblingValues}</span>
    </div>
  );
};