Expand All

  Getting Started



  Row Models





Github stars make projects look great. Please help, donate a star, it's free.
Get informed on releases and other ag-Grid news only - never spam.
Follow on Twitter

Enterprise Row Model

Lab Feature

Enterprise Row Model is currently in development, subject to change and not all edge cases are coded for. The purpose of including this feature in the latest release is to present the idea to our customers and get feedback. Feel free to look, try it out, and give feedback. However please do not plan a production release without first talking to us so we know what dependencies we have.

Check out YouTube Movie explaining what the Enterprise Row Model is.


The default row model for ag-Grid, the In Memory row model, will do grouping and aggregation for you if you give it all the data. If the data will not fit in the browser because it is to large, then you can use either Infinite Scrolling row model or Viewport row model. However these row models cannot do grouping or aggregation.

The Enterprise Row Model presents the ability to have grouping and aggregation on large datasets by delegating the aggregation to the server and lazy loading the groups.

Some users might simply see it as lazy loading group data from the server. Eg if you have a managers database table, you can display a list of all managers, then then click 'expand' on the manager and the grid will then request to get the 'employees' for that manager.

Or a more advanced use case would be to allow the user to slice and dice a large dataset and have the backend generate SQL (or equivalent if not using a SQL store) to create the result. This would be similar to how current data analysis tools work, a mini-Business Intelligence experience.

How it Works

You provide the grid with a datasource. The interface for the datasource is as follows:

// datasource for enterprise row model
interface IEnterpriseDatasource {

    // just one method, to get the rows
    getRows(params: IEnterpriseGetRowsParams): void;

The getRows takes the following parameters:

interface IEnterpriseGetRowsParams {

    // details for the request
    request: IEnterpriseGetRowsRequest;

    // success callback, pass the rows back the grid asked for
    successCallback(rowsThisPage: any[]): void;

    // fail callback, tell the grid the call failed so it can adjust it's state
    failCallback(): void;

The request, with details about what the grid needs, has the following structure:

interface IEnterpriseGetRowsRequest {

    // details for the request
    rowGroupCols: ColumnVO[];

    // columns that have aggregations on them
    valueCols: ColumnVO[];

    // what groups the user is viewing
    groupKeys: string[];

    // if filtering, what the filter model is
    filterModel: any;

    // if sorting, what the sort model is
    sortModel: any;

// we pass a VO (Value Object) of the column and not the column itself,
// so the data can be converted to JSON and passed to server side
export interface ColumnVO {
    id: string;
    displayName: string;
    field: string;
    aggFunc: string;

All the interfaces above is a lot to take in. The best thing to do is look at the examples below and debug through them with teh web console and observed what is passed back as you interact with the grid.

Example - Predefined Master Detail - Mocked Server

Below shows an example of predefined master / detail using the olympic winners. It is pre-defined as we set the grid with a particular grouping, and then our datasource knows that the grid will either be asking for the top level nodes OR the grid will be looking for the lower level nodes for a country.

In your application, your server side would know where to get the data based on what the user is looking for, eg if using a relational database, it could go to the 'countries' table to get the list of countries and then the 'winners' table to get the details as the user expands the group.

In the example, the work your server would do is mocked for demonstrations purposes (as the online examples are self contained and do not contact any servers).

Example - Slice and Dice - Mocked Server

Below shows an example of slicing and dicing the olympic winners. The user has full control over what they aggregate over by dragging the columns to the group drop zone. For example, in the example below, you can remove the grouping on 'country' and group by 'year' instead, or you can group by both.

For your application, your server side would need to understand the requests from the client. Typically this would be used in a reporting scenario, where the server side would build SQL (or the SQL equivalent if using a no-SQL data store) and run it against the data store.

The example below mocks a data store for demonstration purposes.

Example - Slice and Dice - Real Server

It is not possible to put up a full end to end example our the documentation website, as we cannot host servers on our website, and even if we did, you would not be able to run it locally. Instead we have put a full end to end example in Github at https://github.com/ceolter/ag-grid-enterprise-mysql-sample/ and you can also see it working on our YouTube Movie .

The example puts all the olympic winners data into a MySQL database and creates SQL on the fly based on what the user is querying. This is a full end to end example of the type of slicing and dicing we want ag-Grid to be able to do in your enterprise applications.

Example - Pagination with Enterprise Row Model

To enable pagination when using the enterprise row model, all you have to do is turning pagination on with pagination=true. Find below an example.

What's Left To DO?

If you are excited about using this new row model in production, then you will want to know what changes to expect before we mark it as a 'ready for production' feature. This following is a list of items we indent doing:

  1. Infinite Scrolling: The grid works great at handling large data, as long as each groups children is a small set. For example, if grouping by country, shop and widget, you could have 50 countries, 50 shops in each country, and 100 widgets in each shop. That means you will at most take 100 items back from the server in one call even thought there are 250,000 (50x50x100) widgets in total. However if the user decided to remove all grouping, and bring back all low level rows, then that is a problem as the grid will ask from 250,000 items. It is our plan to implement infinite scrolling (similar to the infinite scrolling row model) for each level of the grouping tree, so each group node will effectively have it's own infinite scroll, so the grid will in theory be able to handle an infinite amount of data, no matter how many children a particular group has, and have this infinite amount of data sliced and diced using the Enterprise Row Model.
  2. Caching Expiring of Data: As a follow on from implementing infinite scrolling, data will also need to be cached and purged. Purging is important so the user is able to continually open and close groups with the browser indefinitely filling it's memory.
  3. Server Side Support: Above we presented a demo of using MySQL as a client side database for generating SQL on the fly to do dynamic slicing and dicing of data from a Relational SQL database. We could extend our server side implementations to cover many of the popular SQL and no-SQL databases, in both JavaScript (for those doing NodeJS servers) and Java (for those working in big enterprise, where Java is dominant for server side development).


We have released this unfinished iteration of the Enterprise Row Model to get feedback. If you have an opinion or ideas, please place comments below. If you think it's a good idea, please upvote us on Reddit (or be the first person to create a Reddit post about it).