Headless Pivot
Use createPivotController when your application needs analytical results, exports or custom presentation without creating a revo-grid. The controller owns report execution and committed state; your app decides how to display the returned rows.
Live example
Section titled “Live example”Execute Pivot without a grid
Refresh a real Pivot controller and inspect the returned result without any grid.
This example renders the controller’s returned values in an ordinary HTML table. There is no RevoGrid element or grid plugin. Use Refresh to execute again, or select the source/query example to replace facts and filter the result.
Execute a report
Section titled “Execute a report”Download the executable example into an application with Pivot installed and run:
node customer-example.mjsIt imports only @revolist/pivot/headless, prints real tables and asserts strict AVG, nonadditive totals, formulas, ranking, sorting, exports and refusal/recovery. No database or browser is needed. The downloadable example uses explicit V2 numeric policies for its advanced cases. The smaller starter below focuses on the controller lifecycle.
import { createPivotController, type PivotReport } from '@revolist/pivot/headless';const report: PivotReport = { kind: 'revogrid:pivot.report', version: 1, fields: [ { id: 'region', sourceProp: 'region' }, { id: 'sales', sourceProp: 'sales' }, ], rows: ['region'], columns: [], filters: [], measures: [{ id: 'total', fieldId: 'sales', aggregator: 'sum' }],};const controller = createPivotController({ report, source: [{ region: 'North', sales: 10 }, { region: 'North', sales: 5 }],});try { const outcome = await controller.refresh(); if (outcome.status === 'failed') throw new Error(outcome.error.message); console.table(controller.getSnapshot().view?.model.source); // North: 15} finally { controller.dispose();}Creation validates metadata synchronously and starts idle (autoLoad defaults to false). Catch validation exceptions as well as failed operation outcomes. During loading/failure, display the retained committed view and the pending/error state separately. Do not save a failed pending report as if it committed.
Updating and disposing
Section titled “Updating and disposing”Read controller.getSnapshot() for the accepted view, loading state and errors. Subscribe when your app needs updates, and unsubscribe/dispose on teardown. replaceSource() replaces facts; replaceQuery() changes analytical query/window options. Report commands update layout and measures.
A headless controller may also bind a server adapter. Headless means the calculation is independent of grid rendering, not that it must run locally. Its aggregation execution pin must match the selected engine.
For grid installation return to Getting started; for controller limits, failure states and recovery see Execution and limits.
Continue learning
Section titled “Continue learning”Headless reference · Calculated values · Report persistence.