Data Operation HelpersPremium
Data Query exports individual helper functions for each data operation. The process function combines all of them in a single call.
Sorting
To sort an array by one or more fields, use orderBy. The function accepts a data array and one or more SortDescriptor objects.
The code snippet below demonstrates basic sorting:
import { orderBy, SortDescriptor } from '@progress/kendo-data-query';
const sort: SortDescriptor[] = [
{ field: 'department', dir: 'asc' },
{ field: 'salary', dir: 'desc' }
];
const sorted = orderBy(employees, sort);
/*
Output:
[
{ id: 3, department: 'Engineering', salary: 105000, ... },
{ id: 1, department: 'Engineering', salary: 95000, ... },
{ id: 5, department: 'Engineering', salary: 88000, ... },
{ id: 2, department: 'Marketing', salary: 72000, ... },
{ id: 4, department: 'Marketing', salary: 68000, ... },
]
*/Custom Comparators
You can provide a custom comparator function for a field to override the default comparison behavior. The comparator receives two items and must return a negative number, zero, or a positive number.
Use this when the natural sort order of the stored values does not match the intended display order — for example, when a field holds a severity string and you need critical before high before medium before low.
import { orderBy, SortDescriptor } from '@progress/kendo-data-query';
const SEVERITY_RANK: Record<string, number> = { critical: 0, high: 1, medium: 2, low: 3 };
const descriptor: SortDescriptor[] = [{
field: 'severity',
compare: (a, b) => SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity]
}];
const sorted = orderBy(incidents, descriptor);
/*
Output:
[
{ id: 'P-103', title: 'Data loss on submit', severity: 'critical' },
{ id: 'P-101', title: 'Login timeout', severity: 'high' },
{ id: 'P-104', title: 'Missing pagination', severity: 'high' },
{ id: 'P-102', title: 'Slow report export', severity: 'medium' },
{ id: 'P-105', title: 'Tooltip misaligned', severity: 'low' }
]
*/Filtering
To filter an array, use filterBy. The function accepts a data array as the first argument and a filter descriptor object as the second argument — either a single FilterDescriptor or a CompositeFilterDescriptor for multiple conditions. Composite filters can be nested to any depth.
The code snippet below demonstrates a composite filter that returns only shipped orders above a minimum value:
import { filterBy, CompositeFilterDescriptor } from '@progress/kendo-data-query';
const filter: CompositeFilterDescriptor = {
logic: 'and',
filters: [
{ field: 'status', operator: 'eq', value: 'Shipped' },
{ field: 'total', operator: 'gte', value: 500 }
]
};
const filtered: object[] = filterBy(orders, filter);
/*
Output:
[
{ "customer": "Acme Corp", "status": "Shipped", "total": 1250.00, ... },
{ "customer": "Initech LLC", "status": "Shipped", "total": 895.75, ... }
]
*/The following table lists the supported operators and the types they apply to:
| Operator | Applies to |
|---|---|
eq, neq | All types |
isnull, isnotnull | All types |
lt, lte, gt, gte | Numbers, dates |
startswith, endswith, contains, doesnotcontain | Strings |
isempty, isnotempty | Strings |
Grouping
To split an array into groups, use groupBy. The function accepts a data array as the first argument and an array of GroupDescriptor objects as the second argument.
Note:
groupBydoes not apply the sort direction specified in aGroupDescriptor. Passgroupdescriptors throughprocessinstead when you need sorted groups.
The code snippet below demonstrates grouping orders by sales region:
import { groupBy, GroupDescriptor, GroupResult } from '@progress/kendo-data-query';
const group: GroupDescriptor[] = [{ field: 'region' }];
const grouped: GroupResult[] = groupBy(orders, group) as GroupResult[];
/*
Output:
[
{
"field": "region", "value": "West", "aggregates": {},
"items": [
{ "orderId": 1051, "customer": "Acme Corp", "region": "West", "total": 1250.00 },
{ "orderId": 1053, "customer": "Initech LLC", "region": "West", "total": 895.75 }
]
},
{ "field": "region", "value": "East", "aggregates": {}, "items": [ ... ] },
{ "field": "region", "value": "South", "aggregates": {}, "items": [ ... ] }
]
*/Aggregates
To compute aggregate values over an array, use aggregateBy. The function accepts a data array as the first argument and an array of AggregateDescriptor objects as the second argument.
Supported aggregate functions are sum, average, count, min, max.
The code snippet below demonstrates computing team-wide sales metrics from individual sales rep records:
import { aggregateBy, AggregateDescriptor, AggregateResult } from '@progress/kendo-data-query';
const aggregates: AggregateDescriptor[] = [
{ field: 'rep', aggregate: 'count' },
{ field: 'revenue', aggregate: 'sum' },
{ field: 'revenue', aggregate: 'average' },
];
const result: AggregateResult = aggregateBy(sales, aggregates);
/*
Output:
{
"rep": { "count": 5 },
"revenue": { "sum": 620550, "average": 124110 },
}
*/
Combined Operations with process
The process function applies sort, filter, group, and aggregate operations simultaneously. The function accepts a data array as the first argument and a State object as the second argument, and returns a DataResult object.
The code snippet below demonstrates how to filter, sort, and group a product catalog in a single call:
import { process, State, DataResult } from '@progress/kendo-data-query';
const state: State = {
group: [{ field: 'category', aggregates: [
{ aggregate: 'sum', field: 'price' },
{ aggregate: 'sum', field: 'stock' }
]}],
sort: [{ field: 'price', dir: 'desc' }],
filter: { logic: 'or', filters: [
{ field: 'discontinued', operator: 'eq', value: true },
{ field: 'price', operator: 'lt', value: 50 }
]}
};
const result: DataResult = process(products, state);
/*
Output:
{
"data": [
{ "field": "category", "value": "Accessories", "aggregates": { "price": { "sum": 78 }, "stock": { "sum": 150 } }, "items": [ ... ] },
{ "field": "category", "value": "Electronics", "aggregates": { "price": { "sum": 19 }, "stock": { "sum": 200 } }, "items": [ ... ] }
],
"total": 3
}
*/Distinct Values
To extract unique values for a field from an array, use distinct. The function accepts a data array and a field name or a custom Comparer function as the second argument, and returns an array containing only the first occurrence of each unique value.
This is useful for populating filter dropdowns from the current dataset.
The code snippet below demonstrates extracting distinct product categories:
import { distinct } from '@progress/kendo-data-query';
const categories = distinct(products, 'category');
/*
Output:
[
{ name: 'Laptop Pro 15', category: 'Electronics', ... },
{ name: 'Wireless Mouse', category: 'Accessories', ... }
]
*/