Angular DataTable server side big data query
Get data by paged list: 1. Angular Datatable Server Side Query, 2. .Net Core
├── @types/datatables.net-buttons@1.4.7 ├── @types/datatables.net@1.10.21 ├── angular-datatables@13.0.1 ├── datatables.net-buttons-dt@2.2.2 ├── datatables.net-buttons@2.2.2 ├── datatables.net-dt@1.12.1 ├── datatables.net-staterestore-dt@1.1.1 ├── datatables.net@1.11.4
// Html
<div align="right" class="pb-1" >
<div class="controls" *ngIf="isLoading">
<mat-progress-bar mode="indeterminate" color="primary" aria-label="Loading content"> </mat-progress-bar>
</div>
</div>
<div class="container-fluid h-100">
<table id ="recordtable" class="table table-bordered table-striped table-hover" datatable [dtOptions]="dtOptions"
style="width:100%">
<thead class="table-dark">
<tr align="center" class="align-middle center">
<th>Tech Name</th>
<th>Customer</th>
<th>Job No</th>
<th>Record No</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let dataItem of RecordList" scope="row">
<td>{{dataItem.techName}}</td>
<td>{{dataItem.customerName}}</td>
<td>{{dataItem.jobNo}}</td>
<td><span class="badge bg-info" > {{dataItem.natano}} </span></td>
</tr>
</tbody>
</table>
</div>
// Component.ts
buildDtOptions() {
///https://datatables.net/reference/option/dom
// var colSettings = [];
this.dtOptions = {
scrollY: 750,
scrollX: true,
scrollCollapse: true,
order: [[0, 'desc']],
ordering: true,
pagingType: 'full_numbers',
pageLength: 20,
processing: true,
autoWidth: false,
lengthMenu: [
[10, 20, 50, 100, 1000, -1],
[10, 20, 50, 100, 1000, 'All'],
],
columnDefs: [
{
width: "auto",
targets: [1],
visible: false
}],
fixedColumns: true,
stateSave: true,
dom: 'Blfrtip',
buttons: [
{
extend: 'createState',
config: {
creationModal: true,
toggle: {
columns: {
search: true,
visible: true
},
length: true,
order: true,
paging: true,
scroller: true,
search: true,
searchBuilder: true,
searchPanes: true,
select: true
}
}
},
'savedStates',
'removeAllStates',
'colvis',
'copy', 'csv', 'pdf', 'excel','print',
],
serverSide: true,
responsive: true,
ajax: (dtParameters: any, callback: any) => {
this.isLoading = true;
this.weighingService.getDataTablesDataPagedList(dtParameters)
.pipe(
finalize(() => {
this.isLoading = false;
})
)
.subscribe({
next: resp => {
callback({
recordsTotal: resp.recordsTotal,
recordsFiltered: resp.recordsFiltered,
data: resp.data // set data
});
this.isLoading = false;
},
error: error => {
this.toastr.error(error)
}
});
},
columns: [
{ data: 'no' },
{ data: 'customer' },
{ data: 'amount' },
{ data: 'rego' },
{ data: 'status' },
{ data: 'timestamp' },
],
};
}
// Service.ts
//dtParameters: DataTablesOptions
public getDataTablesDataPagedList(dtParameters: any): Observable<DataTableResponse> {
const body=JSON.stringify(dtParameters);
const headers = { 'Content-Type': 'application/json'};
return this.httpClient.post<DataTableResponse>(this.rootURL + 'api/natarecord/pagelist', body,{ headers}).pipe(map(res => res));
}
// Model
export class DataTableResponse {
data!: any[];
draw!: number;
recordsFiltered!: number;
recordsTotal!: number;
}
// angular.json
"styles": [
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"src/scss/styles.scss",
"node_modules/ngx-toastr/toastr.css",
"node_modules/datatables.net-dt/css/jquery.dataTables.min.css",
"node_modules/datatables.net-buttons-dt/css/buttons.dataTables.min.css",
"node_modules/datatables.net-staterestore-dt/css/stateRestore.dataTables.min.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.js",
"node_modules/jszip/dist/jszip.js",
"node_modules/datatables.net/js/jquery.dataTables.min.js",
"node_modules/datatables.net-buttons/js/dataTables.buttons.min.js",
"node_modules/datatables.net-buttons/js/buttons.colVis.min.js",
"node_modules/datatables.net-buttons/js/buttons.flash.min.js",
"node_modules/datatables.net-buttons/js/buttons.html5.min.js",
"node_modules/datatables.net-buttons/js/buttons.print.min.js",
"node_modules/datatables.net-staterestore/js/dataTables.stateRestore.min.js"
],
// .Net Core Page Service
public class PagedList<T> : List<T>
{
public int CurrentPage { get; private set; }
public int TotalPages { get; private set; }
public int PageSize { get; private set; }
public int TotalCount { get; private set; }
public bool HasPrevious => CurrentPage > 1;
public bool HasNext => CurrentPage < TotalPages;
public PagedList(List<T> items, int count, int pageNumber, int pageSize)
{
TotalCount = count;
PageSize = pageSize;
CurrentPage = pageNumber;
TotalPages = (int)Math.Ceiling(count / (double)pageSize);
AddRange(items);
}
public static PagedList<T> ToPagedList(IQueryable<T> source, int pageNumber, int pageSize)
{
var count = source.Count();
var items = source.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();
return new PagedList<T>(items, count, pageNumber, pageSize);
}
}
// .Net Core Page Model
public class PageParameters
{
public int Draw { get; set; }
public List<Column> Columns { get; set; }
public List<Order> Order { get; set; }
public int Start { get; set; }
public int Length { get; set; }
public Search Search { get; set; }
public string SearchText => Search.Value ?? "";
}
public class Order
{
[JsonPropertyName("column")]
public int Column { get; set; }
[JsonPropertyName("dir")]
public string Dir { get; set; }
}
public class Column
{
[JsonPropertyName("data")]
public string Data { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("searchable")]
public bool Searchable { get; set; }
[JsonPropertyName("orderable")]
public bool Orderable { get; set; }
[JsonPropertyName("search")]
public Search Search { get; set; }
}
public class DataTableResponse<T>
{
public List<T> Data { get; set; }
public int draw { get; set; }
public int recordsFiltered { get; set; }
public int recordsTotal { get; set; }
}
// .Net Core Page Controlar
[HttpPost]
[Route("api/natarecord/pagelist/{pageParameters?}")]
public IActionResult GetPagelist([FromBody] PageParameters pageParameters)
// public Task<ActionResult<IEnumerable<RecordViewModel>>> GetPagelist([FromBody] PageParameters pageParameters)
{
var records = _repo.GetRecords(pageParameters);
_logger.LogDebug($"Returned {records.TotalCount} records from database.");
var result = _mapper.Map<List<RecordViewModel>>(records);
DataTableResponse<RecordViewModel> dataResponse = new DataTableResponse<RecordViewModel>();
dataResponse.Data = result;
dataResponse.recordsTotal = records.TotalCount;
dataResponse.recordsFiltered = records.TotalCount;
return Ok(dataResponse);
}
// .Net Core Page Repository
//pagelist
public PagedList<NATARecord> GetRecords(PageParameters pageParameters)
{
return PagedList<NATARecord>.ToPagedList(FindAll()
.Where(x => x.CustomerName.Contains(pageParameters.SearchText) || x.JobNo.Contains(pageParameters.SearchText) || x.TechName.Contains(pageParameters.SearchText))
.OrderByDescending(x => x.Id),
pageParameters.Draw,
pageParameters.Length);
}
//pagelist
private IQueryable<Weighing> FindAll()
{
return this._context.Set<Weighing>()
.AsNoTracking();
}
Last updated