- Home
- Forum
- Angular - EJ 2
- Server side pagination,sorting,grouping
Server side pagination,sorting,grouping
Hi,
As of now in my application I am fetching all the data and binding it to grid and pagination,sorting and grouping is done on client side. I was wondering as the data will grow this will have performance issue like getting 5K records at a time and binding them to grid. Do you think this will be an issue binding such a huge records to grid?
So I wanted to understand how can I get server side pagination/sorting and grouping implemented.
Here is how I am binding data to grid -
on init -
GetAll() {
this._myService.getAll('', this.maxResultCount, this.skipCount).subscribe(result => {
this.dataList = result.items;
})
}
and dataList is used as datasource for the grid.
<ejs-grid #dataGrid [dataSource]='dataList ' [enableHover]='false' [searchSettings]='false' allowPaging='true' allowSorting="true" [toolbar]='false' [allowGrouping]="true" [groupSettings]="groupOptions" [pageSettings]='pageSettings'>
<e-column ...></e-column>
</ejs-grid>
If user is sorting on a column which event gets triggered - where I can call my service method and pass the name of column to sort?
If user is navigating between pages - which event is triggered - where I can call my service method and pass the pageindex or count to skip records?
If user is grouping - which event is triggered - and what is the expected data structure and how does it work with pagination? Or can I just sort records based on grouping column and do grouping on client side?
Your help is much appreciated.
Thanks,
Sunita
SIGN IN To post a reply.
14 Replies
TS
Thavasianand Sankaranarayanan
Syncfusion Team
April 11, 2019 12:23 PM UTC
Hi Sunita,
Greeting from Syncfusion.
By default, Grid rendered based on the cell element while using large amount of data then it take considerable time to render the Grid. As per your requirement, we suggest you to bind the actionBegin event to find out grid actions such as paging, sorting, filtering etc., and their arguments (current page ,previous page, sort direction and column name etc).
Help documentation : https://ej2.syncfusion.com/angular/documentation/api/grid/#actionbegin
We have data manager to access remote(server) data so please check the below documentation for more information about data binding based on your service you may use any of our adaptor.
Note: By default, Grouping will be done by client side only.
Please get back to us if you need further assistance.
Regards,
Thavasianand S.
SU
Sunita
April 13, 2019 04:46 PM UTC
Hello Thavasianand,
As per your suggestion "actionBegin event" helps me to do server side pagination and sorting. Thanks for your help. But I am not sure how to do grouping. If it is done on client side then it will be based on the records as per page size and will not consider all records in db.
Below url talks about server side grouping but I am not sure how can I implement it in our application -
Can you please guide me on how can I achieve server side grouping ? Or is it possible only to return grouped rows first and then on expand load its respective rows (lazy loading) ? I need grouping feature of grid but it has to be server side.
Help appreciated.
Thanks,
Sunita
SU
Sunita
April 14, 2019 12:55 PM UTC
Hello Thavasianand,


This is again related to server side pagination I am trying to implement using actionBegin() event. But every time I click on any page number it resets to 1. Please find below code - I am not sure what is wrong with my code. actionBegin() for paging is fired twice.
[pageSettings]='pageSettings' (actionBegin)="onActionBegin($event)" (dataBound)="dataBound($event)" (beforeDataBound)="beforeDataBound($event)">
pagesettings:
this.pageSettings = { pageSizes: true, pageSize: this.defaultPageSzie, pageCount: 0, currentPage: 1 };
code-
Note: on init I am calling GetAll(); (for the first time binding)
Help me to resolve this issue.
Thank,
Sunita
TS
Thavasianand Sankaranarayanan
Syncfusion Team
April 15, 2019 01:25 PM UTC
Hi Sunita,
Thanks for your update.
In your application, you are assigning value for currentPage(pageSettings) property dynamically so that it call actionBegin event twice. As per your requirement, we suggest you to use observables that will helps you to bind the custom data and handled Grid actions in server side. Based on the dataStateChange event arguments you can perform grid actions and return result to Grid.
Please refer the below help docuemantion link for more information.
Help docuemantion : https://ej2.syncfusion.com/angular/documentation/grid/observables/?no-cache=1#data-binding
If you are not comfortable with async-pipe then we suggest you to refer the below link(Here we have subscribe the observables).
Regards,
Thavasianand S.
SU
Sunita
April 15, 2019 04:25 PM UTC
Hello Thavasianand,
I will try to implement it is using observables and async pipe. Thanks for your suggestion. Hope it works as per my requirement.
Can you please also help me with grouping -
If it is done on client side then it will be based on the records as per page and will not consider all records in db.
Below url talks about server side grouping but I am not sure how can I implement it when using observables and async pipe -
Can you please guide me on how can I achieve server side grouping ? Or is it possible only to return grouped rows first and then on expand load its respective rows (lazy loading) ? I need grouping feature of grid but it has to be server side.
Thanks,
Sunita
TS
Thavasianand Sankaranarayanan
Syncfusion Team
April 17, 2019 03:11 AM UTC
Hi Sunita,
Thanks for your update.
As per your suggestion, we have created a sample(Angular with Core) and perform grouping in sever side(like EJ1). In the below sample, we have used urlAdaptor and handle the grid actions in server side. Please refer the below sample and documentation for more information.
[ClientApp/app/components/fetchdata.component.ts]
|
ngOnInit(): void {
this.data = new DataManager({
url: 'Home/UrlDatasource',
adaptor: new UrlAdaptor
});
} |
[HomeController.cs]
|
public IActionResult UrlDatasource([FromBody]DataManagerRequest dm)
{
IEnumerable DataSource = OrdersDetails.GetAllRecords();
DataOperations operation = new DataOperations();
if (dm.Sorted != null && dm.Sorted.Count > 0) //Sorting
{
DataSource = operation.PerformSorting(DataSource, dm.Sorted);
}
if (dm.Where != null && dm.Where.Count > 0) //Filtering
{
DataSource = operation.PerformFiltering(DataSource, dm.Where, dm.Where[0].Operator);
}
IEnumerable GroupDs = new List<object>(); ;
if (dm.Group != null)
{
GroupDs = operation.PerformSelect(DataSource, dm.Group);
}
int count = DataSource.Cast<OrdersDetails>().Count();
if (dm.Skip != 0)
{
DataSource = operation.PerformSkip(DataSource, dm.Skip); //Paging
}
if (dm.Take != 0)
{
DataSource = operation.PerformTake(DataSource, dm.Take);
}
return dm.RequiresCounts ? Json(new { result = DataSource, count = count, groupDs = GroupDs }) : Json(DataSource);
}
|
|
|
Sample : http://www.syncfusion.com/downloads/support/directtrac/general/ze/angular-core-server-group784468318
Help documentation: https://ej2.syncfusion.com/aspnetcore/documentation/grid/data-binding/?no-cache=1#datatable-with-on-demand-grid-actions
Regards,
Thavasianand S.
SU
Sunita
April 17, 2019 05:50 AM UTC
Hello Thavasianand,
As per your suggestion I have already made changes to application to use observables. Please suggest server side grouping based on that.
Also as per your code below - all records are fetched at once on web-server again can be performance issue.
Does the grid support lazy loading - getting grouped rows first and then on expand of grouped header row load child rows?
Thanks,
Sunita
TS
Thavasianand Sankaranarayanan
Syncfusion Team
April 22, 2019 12:25 PM UTC
Hi Sunita,
Thanks for your update.
By default, while perform grouping it send server request(server side grouping) based on the field we have returned the corresponding grouped column records in server side (while grouping) and then calculate the group caption(14 items) and aggregates at client side using the server data.
Currently, we don’t have support like lazy loading in Grid. We are checking the feasibility at our end we will let you know once the feature validation complete.
Until then we appreciate your patience.
Regards,
Thavasianand S.
SR
Srinivas
September 20, 2019 06:36 AM UTC
Hi
I am having difficulty in implementing the paging on the grid, it is not showing pages at all.I implemented several grids with paging in other functionality using local data binding, but with remote I am unable to figure out.
html:
<ejs-grid #customerGrid id='grid' class="margin-top-5 expense-grid-margin pane"
allowSorting="true" height='100%' width='100%' allowPaging='true' [allowSelection]='true'
[dataSource]='data | async' (dataSourceChanged)='dataSourceChanged($event)'
(dataStateChange)= 'dataStateChange($event)' [pageSettings]='pageOptions'>
<e-columns>
<e-column type='checkbox' width='30'></e-column>
<e-column field='name' headerText='Name' width='110' [validationRules]='validateRule' hideAtMedia='(min-width: 600px)'></e-column>
<e-column field='id' headerText='Id' isPrimaryKey='true' [visible]='false'></e-column>
</e-columns>
</ejs-grid>component:constructor(private service: CustomerDataService) {
this.data = service;
}
public dataStateChange(state: DataStateChangeEventArgs): void {
this.service.execute(state);
}
public ngOnInit(): void {
this.pageOptions = { pageSize: 10, pageCount: 5, pageSizes: true};
this.validateRule = {required: true};
const state: any = { skip: 1, take: 10 };
this.service.execute(state);
}service:public execute(state: any, headers?: HttpHeaders | null): void {
this.getData(state, headers).subscribe(x => super.next(x as DataStateChangeEventArgs));
}
protected getData(state: DataStateChangeEventArgs, headers?: HttpHeaders | null): Observable<DataStateChangeEventArgs> {
const pageQuery = `pageNumber=${state.skip}&pageSize=${state.take}`;
const baseFilter = new BaseFilter(state.skip, state.take);
let sortQuery = '';
const d = 'd';
const results = 'results';
const count = '__count';
if ((state.sorted || []).length) {
sortQuery = `&$orderby=` + state.sorted.map((obj: Sorts) => {
return obj.direction === 'descending' ? `${obj.name} desc` : obj.name;
}).reverse().join(',');
}
const expandedHeaders = this.prepareHeader(headers);
return this.http.get(this.baseUrl + '?pageNumber=' + baseFilter.pageNumber + '&pageSize=' + baseFilter.pageSize, expandedHeaders)
.map((res: any) => ({
result: state.take > 0 ? res.data.slice(state.skip, state.skip + state.take) : res,
count: res.totalCount
} as DataResult))
.pipe((data: any) => data);
}response json:(data has just one row, but it returns 10 rows actually){"data":[{"id":4927,"name":"test customer","phone":"6301482799","customerAdded":"2019-09-20"],"pageNumber":1,"nextPageNumber":2,"prevPageNumber":1,"lastPage":false,"firstPage":true,"pageSize":10,"totalCount":4746,"totalPageCount":475}
PS
Pavithra Subramaniyam
Syncfusion Team
September 23, 2019 09:22 AM UTC
Hi Srinivas,
Thanks for contacting Syncfusion support.
We have validated the provided information and code example. We suspect that in your application, you are not returning data properly so that it cause the reported problem. We suggest you to return the result and count properly because while using custom binding(or remote data) then we have bind the data to Grid based on the result (JSON object) that you are returned from server.
Please refer the below demo sample for more information.
Regards,
Pavithra S.
SR
Srinivas
September 23, 2019 04:09 PM UTC
Thanks Pavithra,
the response comes as JSON already with two properties result as an array and count as number, thats why I commented response.json() see sample data response
{"result":[{"id":4953,"name":"Amit Kurud","phone":"333222222","customerAdded":"2019-09-23","customerId":"CUS5503266","referralCode":"CgCHbz","notifyReceiver":false,"deviceType":"ANDROID","deviceMake":"OnePlus","deviceModel":"ONEPLUS A6010","os":"1.0.49","premium":false,"webSignup":false},{"id":4952,"name":"Swarup Denre","phone":"322112333","customerAdded":"2019-09-23","customerId":"CUS5502266","referralCode":"6Y6crt","notifyReceiver":false,"deviceType":"ANDROID","deviceMake":"samsung","deviceModel":"SM-A505F","os":"1.0.49","premium":false,"webSignup":false}],"count":4772}
return this.http.get(this.baseUrl + '?pageNumber=' + baseFilter.pageNumber + '&pageSize=' + baseFilter.pageSize, expandedHeaders)
// .pipe(map((response: any) => response.json()))
.pipe(map((response: any) => (<DataResult>{
result: response.result,
count: response.count
})))
.pipe((data: any) => data);
TS
Thavasianand Sankaranarayanan
Syncfusion Team
September 24, 2019 11:55 AM UTC
Hi Srinivas,
Thanks for your update.
By default, if you are returning the result and count then we have bind the data(result) to Grid. We have created a sample for your reference, please refer the sample for more information.
Note: previously provided code snippet you are apply initial skip count as 1 so it return record from 2nd.
Could you please share the issue details and if possible share the sample(or reproduce at our sample) and video to demonstrate the problem that will be helpful for us to validate further and to provide a better solution as soon as possible.
Regards,
Thavasianand S.
NS
Neha Singh
August 31, 2020 08:03 PM UTC
Hello Team,
I need to integrate server side paging and filtering. Can you please provide a sample of this? As in the thread I am getting confused...
Scenario :
Service Call -> url +'?pageSize=' +
param.pageSize +
'&pageNo=' +
param.pageNo
In Query Param I need to pass -> { pageSize: 10, pageNo: 1} // To fetch the response of corresponding page
HTML ->
<ejs-grid
[dataSource]="data"
[allowPaging]="false"
[allowSorting]="true"
[allowFiltering]="true"
[filterSettings]="filterSettings"
>
<e-columns>
<e-column
field="Id"
headerText="id"
textAlign="Left"
width="50"
></e-column>
<e-column
field="Name"
headerText="Name"
textAlign="Left"
width="50"
></e-column>
<e-column
field="location"
headerText="Loc"
textAlign="Left"
width="60"
></e-column>
<e-column
field="deviceTimestamp"
type="date"
headerText="Time"
textAlign="Left"
width="80"
></e-column>
</e-columns>
</ejs-grid>
BS
Balaji Sekar
Syncfusion Team
September 2, 2020 01:16 PM UTC
Hi Sunita,
Thanks for your patience.
Query #1: I need to integrate server side filtering in the custom databinding
Based on your query you can filtering the Grid columns with custom binding data using dataStateChange event of Grid component
In dataStateChange event, we have call the remote service based on the “filterchoicerequest”, “filtersearchbegin” requestType.
When you perform the filtering action, you need to return result data alone in JSON object format.
|
@Component({
selector: "control-content",
templateUrl: `async-pipe.html`,
providers: [OrdersService]
})
export class AsyncPipeComponent {
public state: DataStateChangeEventArgs;
public filterOptions = { type: "Excel" };
constructor(public service: OrdersService) {
this.data = service;
}
public dataStateChange(state: DataStateChangeEventArgs): void {
if (
state.action.requestType === "filterchoicerequest" || state.action.requestType === "filtersearchbegin"
) {
this.service.getData(state).subscribe(e => state.dataSource(e)); // for filterchoicerequest and filtersearchbegin you need to return JSON object alone no need to send count
} else {
this.service.execute(state);
}
} |
|
public execute(state: any): void {
this.getData(state).subscribe(x => super.next(x));
}
public getData(state: DataStateChangeEventArgs): Observable<DataStateChangeEventArgs> {
. . . . .
return this.http
.get(`${this.BASE_URL}?${pageQuery}${sortQuery}${filterQuery}&$count=true`)
.pipe(map((response: any) => response.json()))
.pipe(map((response: any) => {
return state.dataSource === undefined ? (<DataResult>{
result: response['value'],
count: parseInt(response['@odata.count'], 10),
}) : response['value'];
}))
.pipe(map((data: any) => data));
}
}
|
Query #2: I need to integrate server side server-side paging
We analyzed your query with the information provided and we need to confirm that you want to pass pageSize, pageNo values instead of skip, take option to get current page records from remote service data.
If we misunderstood your requirement please share more details about your query that will help to validate further.
Regards,
Balaji Sekar
SIGN IN To post a reply.
- 14 Replies
- 6 Participants
-
SU Sunita
- Apr 10, 2019 11:42 AM UTC
- Sep 2, 2020 01:16 PM UTC