Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 

Repository files navigation

Syncfusion React Pivot Table with HotChocolate GraphQL Backend

A quick start project that demonstrates how to bind remote data from a HotChocolate-powered ASP.NET Core GraphQL service to the Syncfusion React Pivot Table using the GraphQLAdaptor. The sample includes both data retrieval and CRUD operations through GraphQL queries and mutations.


📑 Table of Contents


🚀 Quick Overview

This sample connects the Syncfusion React Pivot Table to an ASP.NET Core backend that exposes a GraphQL endpoint with HotChocolate. The frontend uses the Syncfusion DataManager together with the GraphQLAdaptor, while the backend exposes a query resolver for reading data and mutation resolvers for insert, update, and delete operations.

Component Technology Purpose
Frontend React + Vite + Syncfusion Pivot Table Render the Pivot Table UI and bind remote data
Backend ASP.NET Core + HotChocolate Expose GraphQL queries and mutations
Data layer In-memory sample data Provide a runnable sample without a database
Adaptor GraphQLAdaptor Translate Pivot Table operations into GraphQL requests

💡 The sample uses an in-memory dataset, so changes made through the Pivot Table editing experience are available only for the current process and will be reset when the backend restarts.


✨ Key Features

  • 📊 Remote data binding from a GraphQL endpoint to the Syncfusion Pivot Table
  • 🔄 CRUD support through GraphQL mutations for add, edit, and delete actions
  • 🧩 GraphQL response mapping for the Pivot Table’s expected result and count structure
  • 🧠 Custom GraphQL resolver logic for returning and modifying sample order data
  • 🧱 HotChocolate server setup with CORS enabled for local development
  • 🧾 GraphQL field naming configured with GraphQLName attributes for the sample data model

🛠️ Prerequisites

Make sure the following software is available before running the sample.

Software / Package Version Purpose
.NET SDK 10.0 or later Build and run the ASP.NET Core backend
Node.js 20.x or later Run the React client
npm Latest Install frontend dependencies
Visual Studio / VS Code Latest Edit and run the sample
Syncfusion EJ2 packages Current project dependencies Render the Pivot Table and use the GraphQLAdaptor

The backend project targets .NET 10 in GraphQLAdaptor/GraphQLAdaptor.csproj, and the frontend uses Vite with React in Client/package.json.


📂 Project Structure

react-pivot-table-graphql-hotchocolate/
├── Client/                          # React + Vite frontend
│   ├── src/App.tsx                  # Pivot Table configuration and GraphQLAdaptor setup
│   └── package.json                 # Frontend dependencies and scripts
├── GraphQLAdaptor/                  # ASP.NET Core HotChocolate backend
│   ├── GraphQL/
│   │   ├── Mutation.cs              # GraphQL mutation resolvers
│   │   ├── OrdersReturnType.cs     # Response wrapper with result/count
│   │   └── Query.cs                # GraphQL query resolver
│   ├── Models/OrdersDetails.cs     # Sample order model and in-memory data
│   ├── Program.cs                  # GraphQL server and CORS configuration
│   └── Properties/launchSettings.json
└── README.md                        # This file

🏗️ Architecture and Data Flow

The sample follows a simple request flow:

  1. The Syncfusion Pivot Table is rendered in the React client.
  2. The Pivot Table uses DataManager with the GraphQLAdaptor to send a GraphQL request to the backend.
  3. HotChocolate receives the request, executes the configured query resolver, and returns the dataset.
  4. The GraphQLAdaptor maps the response to the Pivot Table’s expected structure using result and count.
  5. When editing is performed, the adaptor sends GraphQL mutations for insert, update, or delete operations.

Request and response flow

  • Read operation: GraphQLAdaptor sends a GraphQL query document to /graphql.
  • Write operations: GraphQLAdaptor sends GraphQL mutation documents for insert, update, and remove.
  • Backend response: the sample returns an object containing both the data rows and the total count.

The client-side configuration in Client/src/App.tsx uses the GraphQLAdaptor with the following mapping:

response: {
  result: 'orders.result',
  count: 'orders.count'
}

This tells the adaptor to read the result rows from the orders.result property and the total record count from orders.count in the GraphQL response.


⚙️ Backend Implementation

The backend lives in GraphQLAdaptor and is configured as a HotChocolate GraphQL server.

1. GraphQL service setup

The GraphQL server is registered in GraphQLAdaptor/Program.cs. The service is configured to:

  • expose a GraphQL endpoint at /graphql
  • register the query resolver from Query
  • register the mutation resolver from Mutation
  • enable projection support through AddProjections()
  • enable CORS for local development
builder.Services
    .AddGraphQLServer()
    .AddQueryType<Query>()
    .AddMutationType<Mutation>()
    .AddProjections();

2. Sample data model

The sample data model is defined in GraphQLAdaptor/Models/OrdersDetails.cs. It contains a simple in-memory list of sample orders and exposes the following fields:

  • OrderID
  • CustomerID
  • EmployeeID
  • Freight

The model uses GraphQLName attributes so the GraphQL field names match the sample data structure.

3. Query resolver

The query resolver in GraphQLAdaptor/GraphQL/Query.cs returns a wrapper object with both the data rows and the total count:

public OrdersReturnType GetOrders()
{
    var allOrders = OrdersDetails.GetAllRecords();
    var query = allOrders.AsQueryable();
    var totalCount = query.Count();

    return new OrdersReturnType
    {
        Result = query.ToList(),
        Count = totalCount
    };
}

The response shape is defined by GraphQLAdaptor/GraphQL/OrdersReturnType.cs, which exposes:

  • Result: the list of records returned to the Pivot Table
  • Count: the total number of records available

4. Mutation resolvers

The mutation layer in GraphQLAdaptor/GraphQL/Mutation.cs implements the CRUD operations used by the Pivot Table editing experience.

  • AddOrder: inserts a new record into the in-memory list
  • UpdateOrder: updates an existing order based on OrderID
  • DeleteOrder: removes an existing order by OrderID

The mutations receive an input type named OrdersDetailsInput, which contains a subset of the model fields used by this sample:

public class OrdersDetailsInput
{
    [GraphQLName("OrderID")]
    public int? OrderID { get; set; }

    [GraphQLName("CustomerID")]
    public string? CustomerID { get; set; }

    [GraphQLName("EmployeeID")]
    public int? EmployeeID { get; set; }

    [GraphQLName("Freight")]
    public double? Freight { get; set; }
}

5. Custom business logic

The current implementation intentionally keeps the data in memory and does not rely on a database. It also includes simple business behavior:

  • new records are inserted at the beginning of the list
  • updates change only the fields that are provided in the mutation payload
  • delete operations remove the matching record by OrderID

This makes the sample easy to run and understand while still demonstrating the full query/mutation lifecycle.


⚛️ Frontend Integration

The client is implemented in Client/src/App.tsx and configures the Pivot Table to use the GraphQLAdaptor.

1. DataManager configuration

The React app creates a DataManager that points to the local GraphQL endpoint:

const data = new DataManager({
  url: 'http://localhost:5190/graphql/',
  adaptor: new GraphQLAdaptor({
    response: {
      result: 'orders.result',
      count: 'orders.count'
    },
    query: `query GetOrders() {
      orders() {
        result {
          OrderID
          CustomerID
          EmployeeID
          Freight
        }
        count
      }
    }`,
    getMutation: function (action) {
      if (action === 'insert') {
        return `mutation CreateOrder($value: OrdersDetailsInput!) {
          addOrder(input: $value) {
            OrderID
            CustomerID
            EmployeeID
            Freight
          }
        }`;
      }
      if (action === 'update') {
        return `mutation UpdateOrder($key: Int!, $keyColumn: String, $value: OrdersDetailsInput!) {
          updateOrder(key: $key, keyColumn: $keyColumn, input: $value) {
            OrderID
            CustomerID
            EmployeeID
            Freight
          }
        }`;
      }
      if (action === 'remove') {
        return `mutation DeleteOrder($key: Int!) {
          deleteOrder(orderID: $key)
        }`;
      }
      return '';
    }
  }),
  crossDomain: true
});

2. Pivot Table setup

The Pivot Table is configured with rows, columns, and values for the sample data:

  • rows: OrderID
  • columns: CustomerID
  • values: Freight

Editing is enabled through the editSettings configuration so users can add, update, and delete records from the Pivot Table drill-through experience.

3. Primary key handling for CRUD

The beginDrillThrough handler in Client/src/App.tsx marks the OrderID column as the primary key so the Syncfusion DataManager can use it for update and delete operations.


▶️ Running the Sample

You need two terminals: one for the backend and one for the frontend.

1. Start the backend

cd GraphQLAdaptor
dotnet restore
dotnet run

The backend will be available at a local URL such as http://localhost:5190 or https://localhost:7163 based on the launch profile in GraphQLAdaptor/Properties/launchSettings.json.

2. Verify the GraphQL endpoint

Open the browser and navigate to:

http://localhost:5190/graphql/

You can test the endpoint with a query such as:

query {
  orders {
    result {
      OrderID
      CustomerID
      EmployeeID
      Freight
    }
    count
  }
}

3. Start the frontend

Open a second terminal and run:

cd Client
npm install
npm run dev

The Vite development server will start, and the app will typically open at http://localhost:5173/.

4. Confirm the integration

Once both applications are running:

  • the Pivot Table should load data from the GraphQL backend
  • the browser network tab should show GraphQL requests to /graphql
  • editing actions should trigger the corresponding GraphQL mutations

🔧 Troubleshooting

Issue Possible cause Resolution
Empty Pivot Table The query result or response mapping is incorrect Confirm that the GraphQL query returns result and count in the expected shape and that the adaptor mapping points to orders.result and orders.count
CORS errors The browser blocks requests from the frontend origin Ensure CORS is enabled in GraphQLAdaptor/Program.cs and that the backend is running
GraphQL endpoint not reachable The backend is not started or the URL is incorrect Verify the backend URL in Client/src/App.tsx and check the launch profile port
CRUD operations fail The mutation names or input shape do not match the server Confirm that the client uses addOrder, updateOrder, and deleteOrder exactly as implemented in GraphQLAdaptor/GraphQL/Mutation.cs
Data changes are not preserved The sample uses in-memory data Restarting the backend will reset the sample data, because the implementation does not use a persistent database

📚 Additional Resources

  • Syncfusion React Pivot Table documentation
  • HotChocolate documentation
  • GraphQL documentation
  • Syncfusion GraphQLAdaptor documentation

If you want to extend this sample further, the next natural step is to replace the in-memory list with a real data source such as Entity Framework Core, SQL Server, or another persistence layer while keeping the same GraphQL and adaptor configuration.


🤝 Contributing

Contributions are welcome and appreciated! 💖

  1. 🍴 Fork the repository.
  2. 🌿 Create a feature branch: git checkout -b feature/my-awesome-change
  3. 💾 Commit your changes: git commit -m "Add my awesome change"
  4. 📤 Push to your branch: git push origin feature/my-awesome-change
  5. 🔁 Open a Pull Request describing the change and its motivation.

📋 Contribution Guidelines

  • Follow the existing code style in both the React and ASP.NET Core projects.
  • Keep changes focused — one feature or fix per pull request.
  • Update or add documentation (README.md, webapi-adaptor.md) when behavior changes.
  • Test your changes locally against both the backend and frontend before submitting.

📜 License & Support

📄 License

This project is released under the MIT License. You are free to use, modify, and distribute the code in personal and commercial projects. See the LICENSE file for full text.

🛟 Support

⭐ If this project helped you, please consider giving it a star on GitHub — it helps others discover it!


About

A quick start project that demonstrates how to bind remote data from a GraphQL service to the Syncfusion React Pivot Table using the GraphQLAdaptor with a HotChocolate-powered ASP.NET Core backend.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages