CustomAdaptor in Syncfusion React Grid Component
27 Sep 202424 minutes to read
The CustomAdaptor
in the Syncfusion React Grid Component allows to create their own custom adaptors by extending the built-in adaptors. The custom adaptor involves handling the built-in adaptor query process, request and response. The CustomAdaptor
to be allows extending the OData V4 services, enabling efficient data fetching and manipulation. By default, there are three method for CustomAdaptor built-in methods.
Types of CustomAdaptor methods
There are three types of methods in custom adaptors.
ProcessQuery
It handling or executing a query sent to a data source such as database or custom dataService. This query request for data retrieval, insertion, updating, or deletion. The processQuery can be two argument are DataManager
and Query
. The DataManager
argument using change the url value and Query
argument are set the additional parameters value or change the any queries such as sort, filter and group etc.
DataManager
Query
public processQuery(dm: DataManager, query: Query): Object {
dm.dataSource.url = 'https://localhost:xxxx/odata/orders'; //Change the url
query.addParams('Syncfusion in React Grid', 'true'); //Add the additional parameter
const result = super.processQuery.apply(this, arguments as any);
return result;
}
beforeSend
It executed before an request is sent to the server. This function provides an modify the parameter and request headers, data or performing validation.The beforeSend
can be three argument are DataManager
, Request
and Fetch
. The DataManager
argument are provided the dataSource and adaptor value. The Request
argument are sending the custom header by setting the Authorization
. The Settings
argument is optional.
DataManager
Request
Settings
public beforeSend(dm: DataManager, request: Request, settings?: any) {
request.headers.set('Authorization', `Bearer${(window as any).token}`);
super.beforeSend(dm, request, settings);
}
processResponse
It is responsible for handling the response received from a server after the asynchronous request. It performs such as parsing the response data, handling error and preparing the data for consumption. The processResponse
can be multiple arguments are optional.
public processResponse() {
let i = 0;
const original: any = super.processResponse.apply(this, arguments as any);
/* Adding serial number */
if (original.result) {
original.result.forEach((item: any) => setValue('SNo', ++i, item));
}
return original;
}
This guide provides detailed instructions on binding data and performing CRUD (Create, Read, Update, Delete) actions using the CustomAdaptor
by extending the ODataV4Adaptor
in your Syncfusion React Grid Component.
Creating an Custom service
To configure a server with Syncfusion React Grid, you need to follow the below steps:
1. Project Creation:
Open Visual Studio and create an React and ASP.NET Core project named CustomAdaptor. To create an React and ASP.NET Core application, follow the documentation link for detailed steps.
2. Install NuGet Packages
Using the NuGet package manager in Visual Studio (Tools → NuGet Package Manager → Manage NuGet Packages for Solution), install the Microsoft.AspNetCore.OData
NuGet package.
3. Model Class Creation:
Create a model class named OrdersDetails.cs in the server-side Models folder to represent the order data.
using System.ComponentModel.DataAnnotations;
namespace ODataV4Adaptor.Server.Models
{
public class OrdersDetails
{
public static List<OrdersDetails> order = new List<OrdersDetails>();
public OrdersDetails()
{
}
public OrdersDetails(
int OrderID, string CustomerId, int EmployeeID, string ShipCountry)
{
this.OrderID = OrderID;
this.CustomerID = CustomerId;
this.EmployeeID = EmployeeID;
this.ShipCountry = ShipCountry;
}
public static List<OrdersDetails> GetAllRecords()
{
if (order.Count() == 0)
{
int code = 10000;
for (int i = 1; i < 10; i++)
{
order.Add(new OrdersDetails(code + 1, "ALFKI", i + 0, "Denmark"));
order.Add(new OrdersDetails(code + 2, "ANATR", i + 2, "Brazil"));
order.Add(new OrdersDetails(code + 3, "ANTON", i + 1, "Germany"));
order.Add(new OrdersDetails(code + 4, "BLONP", i + 3, "Austria"));
order.Add(new OrdersDetails(code + 5, "BOLID", i + 4, "Switzerland"));
code += 5;
}
}
return order;
}
[Key]
public int? OrderID { get; set; }
public string? CustomerID { get; set; }
public int? EmployeeID { get; set; }
public string? ShipCountry { get; set; }
}
}
4. Build the Entity Data Model
To construct the Entity Data Model for your OData service, utilize the ODataConventionModelBuilder
to define the model’s structure. Start by creating an instance of the ODataConventionModelBuilder
, then register the entity set Orders using the EntitySet<T>
method, where OrdersDetails
represents the CLR type containing order details.
// Create an ODataConventionModelBuilder to build the OData model
var modelBuilder = new ODataConventionModelBuilder();
// Register the "Orders" entity set with the OData model builder
modelBuilder.EntitySet<OrdersDetails>("Orders");
5. Register the OData Services
Once the Entity Data Model is built, you need to register the OData services in your ASP.NET Core application. Here’s how:
// Add controllers with OData support to the service collection
builder.Services.AddControllers().AddOData(
options => options
.Count()
.AddRouteComponents("odata", modelBuilder.GetEdmModel()));
6. Add controllers
Finally, add controllers to expose the OData endpoints. Here’s an example:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;
using ODataV4Adaptor.Server.Models;
namespace ODataV4Adaptor.Server.Controllers
{
[Route("[controller]")]
[ApiController]
public class OrdersController : ControllerBase
{
/// <summary>
/// Retrieves all orders.
/// </summary>
/// <returns>The collection of orders.</returns>
[HttpGet]
[EnableQuery]
public IActionResult Get()
{
var data = OrdersDetails.GetAllRecords().AsQueryable();
return Ok(data);
}
}
}
7. Run the Application:
Run the application in Visual Studio. It will be accessible on a URL like https://localhost:xxxx.
After running the application, you can verify that the server-side API controller is successfully returning the order data in the URL(https://localhost:xxxx/odata/Orders). Here xxxx denotes the port number.
Connecting Syncfusion React Grid to an Custom service extending the ODataV4 service
To integrate the Syncfusion Grid component into your React and ASP.NET Core project using Visual Studio, follow the below steps:
Step 1: Install Syncfusion Package
Open your terminal in the project’s client folder and install the required Syncfusion packages using npm:
npm install @syncfusion/ej2-react-grids --save
npm install @syncfusion/ej2-data --save
Step 2: Adding CSS reference
Include the necessary CSS files in your styles.css
file to style the Syncfusion React component:
@import '../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
@import '../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css';
@import '../node_modules/@syncfusion/ej2-react-grids/styles/material.css';
Step 4: Adding Custom Adaptor
You can create the component file (e.g., CustomAdaptor.tsx). After, you can import the DataManager
and ODataV4Adaptor
from @syncfusion/ej2-data
. Create the own custom adaptor by extending the ODataV4 service. This adaptor execute the three method such as processQuery
, beforeSend
and processResponse
.
-
The
processQuery
method is used to change the URL of your API endpoint and set the additional parameters for executing the query. -
The
beforeSend
method is used to send the custom header forAuthorization
in the request header. -
The
processResponse
method is used to set the value for customize the column for new field isSNo
.
import { setValue } from '@syncfusion/ej2-base';
import { DataManager, ODataV4Adaptor, Query, } from '@syncfusion/ej2-data';
export class SerialNoAdaptor extends ODataV4Adaptor {
public processResponse() {
let i = 0;
const original: any = super.processResponse.apply(this, arguments as any);
/* Adding serial number */
if (original.result) {
original.result.forEach((item: any) => setValue('SNo', ++i, item));
}
return original;
}
public processQuery(dm: DataManager, query: Query): Object {
dm.dataSource.url = 'https://localhost:xxxx/odata/orders';
query.addParams('Syncfusion in React Grid', 'true');
const result = super.processQuery.apply(this, arguments as any);
return result;
}
public beforeSend(dm: any, request: any, settings: any) {
request.headers.set('Authorization', `Bearer${(window as any).token}`);
super.beforeSend(dm, request, settings);
}
}
Step 5: Adding Syncfusion Component
In your component file (e.g., App.tsx), import DataManager
from @syncfusion/ej2-data
and CustomAdaptor
from ./CustomAdaptor
file. Create a DataManager
instance specifying the URL of your API endpoint(https:localhost:xxxx/odata/Orders) using the url
property and set the adaptor CustomAdaptor
.
import { DataManager } from '@syncfusion/ej2-data';
import {CustomAdaptor} from './CustomAdaptor';
import { ColumnDirective, ColumnsDirective, GridComponent } from '@syncfusion/ej2-react-grids';
function App() {
const data = new DataManager({
url:'https://localhost:xxxx/odata/Orders', // Here xxxx represents the port number
adaptor: new CustomAdaptor()
});
return <GridComponent dataSource={data} >
<ColumnsDirective>
<ColumnDirective field='SNo' headerText='SNO' width='150'/>
<ColumnDirective field='OrderID' headerText='Order ID' isPrimaryKey={true} width='150'textAlign='Right'></ColumnDirective>
<ColumnDirective field='CustomerID' headerText='Customer ID' width='150'></ColumnDirective>
<ColumnDirective field='EmployeeID' headerText='Employee ID' width='150'/>
<ColumnDirective field='ShipCountry' headerText='Ship Country' width='150'/>
</ColumnsDirective>
</GridComponent>
};
export default App;
Replace https://localhost:xxxx/odata/Orders with the actual URL of your API endpoint that provides the data in a consumable format (e.g., JSON).
Run the application in Visual Studio. It will be accessible on a URL like https://localhost:xxxx.
Ensure your API service is configured to handle CORS (Cross-Origin Resource Sharing) if necessary.
[program.cs]
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});
});
var app = builder.Build();
app.UseCors();
Handling filtering operation
To enable filter operations in your web application using custom adaptor, you first need to configure the custom adaptor extending the OData support in your service collection. This involves adding the Filter
method within the OData setup, allowing you to filter data based on specified criteria. Once enabled, clients can utilize the $filter query option in your requests to filter for specific data entries.
// Create a new instance of the web application builder
var builder = WebApplication.CreateBuilder(args);
// Create an ODataConventionModelBuilder to build the OData model
var modelBuilder = new ODataConventionModelBuilder();
// Register the "Orders" entity set with the OData model builder
modelBuilder.EntitySet<OrdersDetails>("Orders");
// Add services to the container.
// Add controllers with OData support to the service collection
builder.Services.AddControllers().AddOData(
options => options
.Count()
.Filter() //filtering
.AddRouteComponents("odata", modelBuilder.GetEdmModel()));
import { DataManager } from '@syncfusion/ej2-data';
import {CustomAdaptor} from './CustomAdaptor';
import { ColumnDirective, ColumnsDirective, GridComponent, Filter } from '@syncfusion/ej2-react-grids';
function App() {
const data = new DataManager({
url:'https://localhost:xxxx/odata/Orders', // Replace your hosted link
adaptor: new CustomAdaptor()
});
return <GridComponent dataSource={data} allowFiltering={true}>
<ColumnsDirective>
<ColumnDirective field='SNo' headerText='SNO' width='150'/>
<ColumnDirective field='OrderID' headerText='Order ID' isPrimaryKey={true} width='150'textAlign='Right'></ColumnDirective>
<ColumnDirective field='CustomerID' headerText='Customer ID' width='150'></ColumnDirective>
<ColumnDirective field='EmployeeID' headerText='Employee ID' width='150'/>
<ColumnDirective field='ShipCountry' headerText='Ship Country' width='150'/>
</ColumnsDirective>
<Inject services={[Filter]} />
</GridComponent>
};
export default App;
Single column filtering
Multi column filtering
Handling searching operation
To enable search operations in your web application using custom adaptor, you first need to configure the custom adaptor extending the OData support in your service collection. This involves adding the Filter
method within the OData setup, allowing you to filter data based on specified criteria. Once enabled, clients can utilize the $filter query option in their requests to search for specific data entries.
// Create a new instance of the web application builder
var builder = WebApplication.CreateBuilder(args);
// Create an ODataConventionModelBuilder to build the OData model
var modelBuilder = new ODataConventionModelBuilder();
// Register the "Orders" entity set with the OData model builder
modelBuilder.EntitySet<OrdersDetails>("Orders");
// Add services to the container.
// Add controllers with OData support to the service collection
builder.Services.AddControllers().AddOData(
options => options
.Count()
.Filter() // searching
.AddRouteComponents("odata", modelBuilder.GetEdmModel()));
import { DataManager } from '@syncfusion/ej2-data';
import {CustomAdaptor} from './CustomAdaptor';
import { ColumnDirective, ColumnsDirective, GridComponent, Toolbar, ToolbarItems } from '@syncfusion/ej2-react-grids';
function App() {
const data = new DataManager({
url:'https://localhost:xxxx/odata/Orders', // Replace your hosted link
adaptor: new CustomAdaptor()
});
const toolbar: ToolbarItems[] = ['Search'];
return <GridComponent dataSource={data} toolbar={toolbar}>
<ColumnsDirective>
<ColumnDirective field='OrderID' headerText='Order ID' isPrimaryKey={true} width='150'textAlign='Right'></ColumnDirective>
<ColumnDirective field='CustomerID' headerText='Customer ID' width='150'></ColumnDirective>
<ColumnDirective field='EmployeeID' headerText='Employee ID' width='150'/>
<ColumnDirective field='ShipCountry' headerText='Ship Country' width='150'/>
</ColumnsDirective>
<Inject services={[Toolbar]} />
</GridComponent>
};
export default App;
Handling sorting operation
To enable sorting operations in your web application using custom adaptor, you first need to configure the custom adaptor extending the OData support in your service collection. This involves adding the OrderBy
method within the OData setup, allowing you to sort data based on specified criteria. Once enabled, clients can utilize the $orderby query option in their requests to sort data entries according to desired attributes.
// Create a new instance of the web application builder
var builder = WebApplication.CreateBuilder(args);
// Create an ODataConventionModelBuilder to build the OData model
var modelBuilder = new ODataConventionModelBuilder();
// Register the "Orders" entity set with the OData model builder
modelBuilder.EntitySet<OrdersDetails>("Orders");
// Add services to the container.
// Add controllers with OData support to the service collection
builder.Services.AddControllers().AddOData(
options => options
.Count()
.OrderBy() // sorting
.AddRouteComponents("odata", modelBuilder.GetEdmModel()));
import { DataManager } from '@syncfusion/ej2-data';
import {CustomAdaptor} from './CustomAdaptor';
import { ColumnDirective, ColumnsDirective, GridComponent, Sort } from '@syncfusion/ej2-react-grids';
function App() {
const data = new DataManager({
url:'https://localhost:xxxx/odata/Orders', // Replace your hosted link
adaptor: new CustomAdaptor()
});
return <GridComponent dataSource={data} allowSorting={true}>
<ColumnsDirective>
<ColumnDirective field='SNo' headerText='SNO' width='150'/>
<ColumnDirective field='OrderID' headerText='Order ID' isPrimaryKey={true} width='150'textAlign='Right'></ColumnDirective>
<ColumnDirective field='CustomerID' headerText='Customer ID' width='150'></ColumnDirective>
<ColumnDirective field='EmployeeID' headerText='Employee ID' width='150'/>
<ColumnDirective field='ShipCountry' headerText='Ship Country' width='150'/>
</ColumnsDirective>
<Inject services={[Sort]} />
</GridComponent>
};
export default App;
Single column sorting
Multi column sorting
Handling paging operation
To implement paging operations in your web application using CustomAdaptor by extending the OData, you can utilize the SetMaxTop
method within your OData setup to limit the maximum number of records that can be returned per request. While you configure the maximum limit, clients can utilize the $skip and $top query options in their requests to specify the number of records to skip and the number of records to take, respectively.
// Create a new instance of the web application builder
var builder = WebApplication.CreateBuilder(args);
// Create an ODataConventionModelBuilder to build the OData model
var modelBuilder = new ODataConventionModelBuilder();
// Register the "Orders" entity set with the OData model builder
modelBuilder.EntitySet<OrdersDetails>("Orders");
// Add services to the container.
// Add controllers with OData support to the service collection
builder.Services.AddControllers().AddOData(
options => options
.Count()
.SetMaxTop(null)
.AddRouteComponents("odata", modelBuilder.GetEdmModel()));
import { DataManager } from '@syncfusion/ej2-data';
import {CustomAdaptor} from './CustomAdaptor';
import { ColumnDirective, ColumnsDirective, GridComponent, Page } from '@syncfusion/ej2-react-grids';
function App() {
const data = new DataManager({
url: 'https://localhost:xxxx/odata/Orders', // Replace your hosted link
adaptor: new CustomAdaptor()
});
return <GridComponent dataSource={data} allowPaging={true}>
<ColumnsDirective>
<ColumnDirective field='SNo' headerText='SNO' width='150'/>
<ColumnDirective field='OrderID' headerText='Order ID' isPrimaryKey={true} width='150'textAlign='Right'></ColumnDirective>
<ColumnDirective field='CustomerID' headerText='Customer ID' width='150'></ColumnDirective>
<ColumnDirective field='EmployeeID' headerText='Employee ID' width='150'/>
<ColumnDirective field='ShipCountry' headerText='Ship Country' width='150'/>
</ColumnsDirective>
<Inject services={[Page]} />
</GridComponent>
};
export default App;
Handling CRUD operations
To manage CRUD (Create, Read, Update, Delete) operations using the CustomAdaptor, follow the provided guide for configuring the Syncfusion Grid for editing and utilize the sample implementation of the OrdersController
in your server application. This controller handles HTTP requests for CRUD operations such as GET, POST, PATCH, and DELETE.
To enable CRUD operations in the Syncfusion Grid component within an React application, follow the below steps:
import { ColumnDirective, ColumnsDirective, GridComponent, ToolbarItems, EditSettingsModel, Toolbar, Edit, Inject } from '@syncfusion/ej2-react-grids';
import { DataManager } from '@syncfusion/ej2-data';
import {CustomAdaptor} from './CustomAdaptor';
function App() {
const data = new DataManager({
url: 'https://localhost:xxxx/odata/Orders', // xxxx denotes port number
adaptor: new CustomAdaptor()
});
const editSettings: EditSettingsModel = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Normal' };
const toolbar: ToolbarItems[] = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
const orderIDRules: object = {required: true};
const customerIDRules: object = {required: true, minLength: 3};
return <GridComponent dataSource={data} editSettings={editSettings} toolbar={toolbar} height={320}>
<ColumnsDirective>
<ColumnDirective field='SNo' headerText='SNO' width='150'/>
<ColumnDirective field='OrderID' headerText='Order ID' isPrimaryKey={true} width='150' textAlign='Right' validationRules={orderIDRules}></ColumnDirective>
<ColumnDirective field='CustomerID' headerText='Customer ID' width='150' validationRules={customerIDRules}></ColumnDirective>
<ColumnDirective field='EmployeeID' headerText='Employee ID' width='150'/>
<ColumnDirective field='ShipCountry' headerText='Ship Country' width='150'/>
</ColumnsDirective>
<Inject services={[Toolbar, Edit]} />
</GridComponent>
};
export default App;
Normal/Inline editing is the default edit mode for the Grid component. To enable CRUD operations, ensure that the isPrimaryKey property is set to true for a specific Grid column, ensuring that its value is unique.
Insert Record
To insert a new record into your Syncfusion Grid, you can utilize the HttpPost
method in your server application. Below is a sample implementation of inserting a record using the OrdersController:
/// <summary>
/// Inserts a new order to the collection.
/// </summary>
/// <param name="addRecord">The order to be inserted.</param>
/// <returns>It returns the newly inserted record detail.</returns>
[HttpPost]
[EnableQuery]
public IActionResult Post([FromBody] OrdersDetails addRecord)
{
if (order == null)
{
return BadRequest("Null order");
}
OrdersDetails.GetAllRecords().Insert(0, addRecord);
return Ok(addRecord);
}
Update Record
Updating a record in the Syncfusion Grid can be achieved by utilizing the HttpPatch
method in your controller. Here’s a sample implementation of updating a record:
/// <summary>
/// Updates an existing order.
/// </summary>
/// <param name="key">The ID of the order to update.</param>
/// <param name="updateRecord">The updated order details.</param>
/// <returns>It returns the updated order details.</returns>
[HttpPatch("{key}")]
public IActionResult Patch(int key, [FromBody] OrdersDetails updatedOrder)
{
if (updatedOrder == null)
{
return BadRequest("No records");
}
var existingOrder = OrdersDetails.GetAllRecords().FirstOrDefault(o => o.OrderID == key);
if (existingOrder != null)
{
// If the order exists, update its properties
existingOrder.CustomerID = updatedOrder.CustomerID ?? existingOrder.CustomerID;
existingOrder.EmployeeID = updatedOrder.EmployeeID ?? existingOrder.EmployeeID;
existingOrder.ShipCountry = updatedOrder.ShipCountry ?? existingOrder.ShipCountry;
}
return Ok(existingOrder);
}
Delete Record
To delete a record from your Syncfusion Grid, you can utilize the HttpDelete
method in your controller. Below is a sample implementation:
/// <summary>
/// Deletes an order.
/// </summary>
/// <param name="key">The key of the order to be deleted.</param>
/// <returns>The deleted order.</returns>
[HttpDelete("{key}")]
public IActionResult Delete(int key)
{
var order = OrdersDetails.GetAllRecords().FirstOrDefault(o => o.OrderID == key);
if (order != null)
{
OrdersDetails.GetAllRecords().Remove(order);
}
return Ok(order);
}