Syncfusion AI Assistant

How can I help you?

Manipulation in React DataManager

20 Feb 202624 minutes to read

The Syncfusion® React DataManager enables easy data manipulation, including creating, updating, and deleting records. It works with both local and remote data sources and offers a consistent interface for handling data operations.

Data manipulation refers to performing CRUD (Create, Read, Update, Delete) actions on a data source. These operations are crucial for managing application data. DataManager streamlines this process by providing a unified approach to executing CRUD operations across different data sources.

Insert

The Syncfusion® DataManager provides a way to add new records to a data source. The insert method allows new entries to be added programmatically.

Insert operations in DataManager enable adding new records by collecting input from form elements and triggering the insertion programmatically, as shown in the example below.

import React, { useEffect, useRef, useState } from 'react';
import { DataManager, JsonAdaptor, Query } from '@syncfusion/ej2-data';
import { data } from './datasource';
import { Row } from './rowTemplate';

const App = () => {
    const [items, setItems] = useState([]);
    const dataManagerRef = useRef(null);

    useEffect(() => {
        const dm = new DataManager({
            json: data.slice(0, 5),
            adaptor: new JsonAdaptor(),
        });

        dataManagerRef.current = dm;

        dm.executeQuery(new Query()).then((e) => {
        setItems(
            e.result.map((row, index) => (
            <Row key={index} {...row} />
            ))
        );
        });
    }, []);

    const insertUpdate = () => {
        const orderId = document.getElementById('OrderID').value;
        const customerId = document.getElementById('CustomerID').value;
        const employeeId = document.getElementById('EmployeeID').value;

        if (!orderId || !dataManagerRef.current) {
            return;
        }

        const rowData = {
            OrderID: +orderId,
            CustomerID: customerId,
            EmployeeID: +employeeId,
        };

        dataManagerRef.current.insert(rowData);

        dataManagerRef.current.executeQuery(new Query()).then((e) => {
        setItems(
            e.result.map((row) => (
            <Row key={row.OrderID} {...row} />
            ))
        );
        });
    };

    return (
        <div>
        <div className="e-form">
            <input type="number" id="OrderID" placeholder="Order ID" />
            <input type="text" id="CustomerID" placeholder="Customer ID" />
            <input type="number" id="EmployeeID" placeholder="Employee ID" />
            <input type="button" id="Insert" value="Insert" onClick={insertUpdate} />
        </div>

        <table id="datatable" className="e-table">
            <thead>
            <tr>
                <th>Order ID</th>
                <th>Customer ID</th>
                <th>Employee ID</th>
            </tr>
            </thead>
            <tbody>{items}</tbody>
        </table>
        </div>
    );
};

export default App;
import * as React from 'react';
import { useEffect, useRef, useState } from 'react';
import { DataManager, JsonAdaptor, Query } from '@syncfusion/ej2-data';
import { data } from './datasource';
import { Row } from './rowTemplate';

const App: React.FC = () => {
  const [items, setItems] = useState<React.ReactNode[]>([]);
  const dataManagerRef = useRef<DataManager | null>(null);

  useEffect(() => {
    const dm = new DataManager({
      json: data.slice(0, 5),
      adaptor: new JsonAdaptor(),
    });

    dataManagerRef.current = dm;

    dm.executeQuery(new Query()).then((e: any) => {
      setItems(
        e.result.map((row: any, index: number) => (
          <Row key={index} {...row} />
        ))
      );
    });
  }, []);

  const insertUpdate = () => {
    const orderId = (document.getElementById('OrderID') as HTMLInputElement).value;
    const customerId = (document.getElementById('CustomerID') as HTMLInputElement).value;
    const employeeId = (document.getElementById('EmployeeID') as HTMLInputElement).value;

    if (!orderId || !dataManagerRef.current) {
      return;
    }

    const rowData = {
      OrderID: +orderId,
      CustomerID: customerId,
      EmployeeID: +employeeId,
    };

    dataManagerRef.current.insert(rowData);

    dataManagerRef.current.executeQuery(new Query()).then((e: any) => {
      setItems(
        e.result.map((row: any) => (
          <Row key={row.OrderID} {...row} />
        ))
      );
    });
  };

  return (
    <div>
      <div className="e-form">
        <input type="number" id="OrderID" placeholder="Order ID" />
        <input type="text" id="CustomerID" placeholder="Customer ID" />
        <input type="number" id="EmployeeID" placeholder="Employee ID" />
        <input type="button" id="Insert" value="Insert" onClick={insertUpdate} />
      </div>

      <table id="datatable" className="e-table">
        <thead>
          <tr>
            <th>Order ID</th>
            <th>Customer ID</th>
            <th>Employee ID</th>
          </tr>
        </thead>
        <tbody>{items}</tbody>
      </table>
    </div>
  );
};

export default App;
import React from 'react';

export const Row = (props) => {
    return (
        <tr>
            <td>{props.OrderID}</td>
            <td>{props.CustomerID}</td>
            <td>{props.EmployeeID}</td>
        </tr>
    );
};
import * as React from 'react';
import { IOrders } from './orders';

export const Row: React.FC<IOrders> = (props) => {
    return (
        <tr>
            <td>{props.OrderID}</td>
            <td>{props.CustomerID}</td>
            <td>{props.EmployeeID}</td>
        </tr>
    );
};

In remote data sources, when the primary key field is an identity field, then it is advised to return the created data in the response.

Update

The Syncfusion® DataManager provides a powerful way to update existing records in a data source without replacing the entire dataset.

Update operations allow modifying specific records through the update method in the DataManager class, ensuring accuracy and consistency in the data. To use the update method, a “KeyField (primary key)” must be defined. This unique identifier allows DataManager to accurately locate and update the corresponding record.

The example includes an input box for editing values and a button that triggers the update method to apply the changes efficiently.

import React, { useEffect, useRef, useState } from 'react';
import { DataManager, JsonAdaptor, Query } from '@syncfusion/ej2-data';
import { data } from './datasource';
import { Row } from './rowTemplate';

const App = () => {
    const [items, setItems] = useState([]);
    const dataManagerRef = useRef(null);

    useEffect(() => {
        const dm = new DataManager({
            json: data.slice(0, 5),
            adaptor: new JsonAdaptor(),
        });

        dataManagerRef.current = dm;

        dm.executeQuery(new Query()).then((e) => {
        setItems(
            e.result.map((row, index) => (
            <Row key={index} {...row} />
            ))
        );
        });
    }, []);

    const updateRecord = () => {
        if (!dataManagerRef.current) return;

        const orderId = document.getElementById('OrderID').value;
        const customerId = document.getElementById('CustomerID').value;
        const employeeId = document.getElementById('EmployeeID').value;

        if (!orderId) return;

        const rowData = {
            OrderID: +orderId,
            CustomerID: customerId,
            EmployeeID: +employeeId,
        };

        dataManagerRef.current.update('OrderID', rowData);

        dataManagerRef.current.executeQuery(new Query()).then((e) => {
        setItems(
            e.result.map((row, index) => (
            <Row key={index} {...row} />
            ))
        );
        });
    };

    return (
        <div>
        <div className="e-form">
            <input type="number" id="OrderID" placeholder="Order ID" />
            <input type="text" id="CustomerID" placeholder="Customer ID" />
            <input type="number" id="EmployeeID" placeholder="Employee ID" />
            <input type="button" id="Update" value="Update" onClick={updateRecord} />
        </div>

        <table id="datatable" className="e-table">
            <thead>
            <tr>
                <th>Order ID</th>
                <th>Customer ID</th>
                <th>Employee ID</th>
            </tr>
            </thead>
            <tbody>{items}</tbody>
        </table>
        </div>
    );
};

export default App;
import * as React from 'react';
import { useEffect, useRef, useState } from 'react';
import { DataManager, JsonAdaptor, Query, ReturnOption } from '@syncfusion/ej2-data';
import { data } from './datasource';
import { Row } from './rowTemplate';

const App: React.FC = () => {
  const [items, setItems] = useState<React.ReactNode[]>([]);
  const dataManagerRef = useRef<DataManager | null>(null);

  useEffect(() => {
    const dm = new DataManager({
      json: data.slice(0, 5),
      adaptor: new JsonAdaptor(),
    });

    dataManagerRef.current = dm;

    dm.executeQuery(new Query()).then((e: ReturnOption) => {
      setItems(
        (e.result as object[]).map((row: object, index: number) => (
          <Row key={index} {...row} />
        ))
      );
    });
  }, []);

  const updateRecord = () => {
    if (!dataManagerRef.current) return;

    const orderId = (document.getElementById('OrderID') as HTMLInputElement).value;
    const customerId = (document.getElementById('CustomerID') as HTMLInputElement).value;
    const employeeId = (document.getElementById('EmployeeID') as HTMLInputElement).value;

    if (!orderId) return;

    const rowData = {
      OrderID: +orderId,
      CustomerID: customerId,
      EmployeeID: +employeeId,
    };

    dataManagerRef.current.update('OrderID', rowData);

    dataManagerRef.current.executeQuery(new Query()).then((e: ReturnOption) => {
      setItems(
        (e.result as object[]).map((row: object, index: number) => (
          <Row key={index} {...row} />
        ))
      );
    });
  };

  return (
    <div>
      <div className="e-form">
        <input type="number" id="OrderID" placeholder="Order ID" />
        <input type="text" id="CustomerID" placeholder="Customer ID" />
        <input type="number" id="EmployeeID" placeholder="Employee ID" />
        <input type="button" id="Update" value="Update" onClick={updateRecord} />
      </div>

      <table id="datatable" className="e-table">
        <thead>
          <tr>
            <th>Order ID</th>
            <th>Customer ID</th>
            <th>Employee ID</th>
          </tr>
        </thead>
        <tbody>{items}</tbody>
      </table>
    </div>
  );
};

export default App;
import React from 'react';

export const Row = (props) => {
    return (
        <tr>
            <td>{props.OrderID}</td>
            <td>{props.CustomerID}</td>
            <td>{props.EmployeeID}</td>
        </tr>
    );
};
import * as React from 'react';
import { IOrders } from './orders';

export const Row: React.FC<IOrders> = (props) => {
    return (
        <tr>
            <td>{props.OrderID}</td>
            <td>{props.CustomerID}</td>
            <td>{props.EmployeeID}</td>
        </tr>
    );
};

Primary key name is required by the update method to find the record to be updated.

Remove

The Syncfusion® DataManager provides a seamless way to delete specific records from a data source without affecting the entire dataset. The remove method handles this operation, and defining a “KeyField (primary key)” is required to uniquely identify each record.

The KeyField parameter enables the remove method to accurately locate and delete the intended entry. The example demonstrates how to delete a record using DataManager, with an input box to enter the KeyField value and a button that triggers the remove method.

import React, { useEffect, useRef, useState } from 'react';
import { DataManager, JsonAdaptor, Query } from '@syncfusion/ej2-data';
import { data } from './datasource';
import { Row } from './rowTemplate';

const App = () => {
  const [items, setItems] = useState([]);
  const dataManagerRef = useRef(null);

  useEffect(() => {
    const dm = new DataManager({
      json: data.slice(0, 5),
      adaptor: new JsonAdaptor(),
    });

    dataManagerRef.current = dm;

    dm.executeQuery(new Query()).then((e) => {
      setItems(
        e.result.map((row, index) => (
          <Row key={index} {...row} />
        ))
      );
    });
  }, []);

  const removeRecord = () => {
    if (!dataManagerRef.current) return;

    const orderId = document.getElementById('OrderID').value;
    if (!orderId) return;

    dataManagerRef.current.remove('OrderID', { OrderID: +orderId });

    dataManagerRef.current.executeQuery(new Query()).then((e) => {
      setItems(
        e.result.map((row, index) => (
          <Row key={index} {...row} />
        ))
      );
    });
  };

  return (
    <div>
      <div className="e-form">
        <input type="number" id="OrderID" placeholder="Order ID" />
        <input type="button" id="Remove" value="Remove" onClick={removeRecord} />
      </div>

      <table id="datatable" className="e-table">
        <thead>
          <tr>
            <th>Order ID</th>
            <th>Customer ID</th>
            <th>Employee ID</th>
          </tr>
        </thead>
        <tbody>{items}</tbody>
      </table>
    </div>
  );
};

export default App;
import * as React from 'react';
import { useEffect, useRef, useState } from 'react';
import { DataManager, JsonAdaptor, Query, ReturnOption } from '@syncfusion/ej2-data';
import { data } from './datasource';
import { Row } from './rowTemplate';

const App: React.FC = () => {
  const [items, setItems] = useState<React.ReactNode[]>([]);
  const dataManagerRef = useRef<DataManager | null>(null);

  useEffect(() => {
    const dm = new DataManager({
      json: data.slice(0, 5),
      adaptor: new JsonAdaptor(),
    });

    dataManagerRef.current = dm;

    dm.executeQuery(new Query()).then((e: ReturnOption) => {
      setItems(
        (e.result as object[]).map((row: object, index: number) => (
          <Row key={index} {...row} />
        ))
      );
    });
  }, []);

  const removeRecord = () => {
    if (!dataManagerRef.current) return;

    const orderId = (document.getElementById('OrderID') as HTMLInputElement).value;
    if (!orderId) return;

    const rowData = { OrderID: +orderId };

    dataManagerRef.current.remove('OrderID', rowData);

    dataManagerRef.current.executeQuery(new Query()).then((e: ReturnOption) => {
      setItems(
        (e.result as object[]).map((row: object, index: number) => (
          <Row key={index} {...row} />
        ))
      );
    });
  };

  return (
    <div>
      <div className="e-form">
        <input type="number" id="OrderID" placeholder="Order ID" />
        <input type="button" id="Remove" value="Remove" onClick={removeRecord} />
      </div>

      <table id="datatable" className="e-table">
        <thead>
          <tr>
            <th>Order ID</th>
            <th>Customer ID</th>
            <th>Employee ID</th>
          </tr>
        </thead>
        <tbody>{items}</tbody>
      </table>
    </div>
  );
};

export default App;
``
import React from 'react';

export const Row = (props) => {
    return (
        <tr>
            <td>{props.OrderID}</td>
            <td>{props.CustomerID}</td>
            <td>{props.EmployeeID}</td>
        </tr>
    );
};
import * as React from 'react';
import { IOrders } from './orders';

export const Row: React.FC<IOrders> = (props) => {
    return (
        <tr>
            <td>{props.OrderID}</td>
            <td>{props.CustomerID}</td>
            <td>{props.EmployeeID}</td>
        </tr>
    );
};

Primary key name and its value are required to find the record to be removed.

Batch edit operation

The Syncfusion® DataManager provides built‑in support for batch processing of CRUD (Create, Read, Update, Delete) operations, enabling efficient handling of multiple edits in a single request. This approach improves performance by grouping multiple add, update, and remove actions, thereby reducing server interactions and overall network overhead.

Batch edits are managed through the saveChanges method, which processes all pending operations together. The example demonstrates this workflow by using input fields to gather the required data for each action and buttons to enqueue the corresponding operations. Finally, the Save Changes button commits all modifications to the data source through the saveChanges method.

import React, { useEffect, useRef, useState } from 'react';
import { DataManager, JsonAdaptor, Query } from '@syncfusion/ej2-data';
import { data } from './datasource';
import { Row } from './rowTemplate';

const App = () => {
    const [items, setItems] = useState([]);
    const dataManagerRef = useRef(null);
    const changesRef = useRef({
        addedRecords: [],
        changedRecords: [],
        deletedRecords: [],
    });

    useEffect(() => {
        const dm = new DataManager({
            json: data.slice(0, 5),
            adaptor: new JsonAdaptor(),
        });

        dataManagerRef.current = dm;

        dm.executeQuery(new Query()).then((e) => {
        setItems(
            e.result.map((row) => (
            <Row key={row.OrderID} {...row} />
            ))
        );
        });
    }, []);

    const action = (e) => {
        const type =
        e.target.value === 'Update'
            ? 'changedRecords'
            : e.target.value === 'Insert'
            ? 'addedRecords'
            : 'deletedRecords';

        const orderId = document.getElementById('OrderID').value;
        const customerId = document.getElementById('CustomerID').value;
        const employeeId = document.getElementById('EmployeeID').value;

        if (!orderId) return;

        changesRef.current[type].push({
            OrderID: +orderId,
            CustomerID: customerId,
            EmployeeID: +employeeId,
        });

        document.getElementById('OrderID').value = '';
        document.getElementById('CustomerID').value = '';
        document.getElementById('EmployeeID').value = '';
    };

    const saveChanges = () => {
        dataManagerRef.current.saveChanges(changesRef.current, 'OrderID');

        dataManagerRef.current.executeQuery(new Query()).then((e) => {
        setItems(
            e.result.map((row) => (
            <Row key={row.OrderID} {...row} />
            ))
        );
        });

        changesRef.current = {
            addedRecords: [],
            changedRecords: [],
            deletedRecords: [],
        };
    };

    return (
        <div>
        <div className="e-form">
            <input type="number" id="OrderID" placeholder="Order ID" />
            <input type="text" id="CustomerID" placeholder="Customer ID" />
            <input type="number" id="EmployeeID" placeholder="Employee ID" />
            <input type="button" id="Insert" value="Insert" onClick={action} />
            <input type="button" id="Update" value="Update" onClick={action} />
            <input type="button" id="Remove" value="Remove" onClick={action} />
        </div>

        <div className="e-form">
            <label>Click to Save changes:</label>
            <input type="button" id="Save" value="Save Changes" onClick={saveChanges} />
        </div>

        <table id="datatable" className="e-table">
            <thead>
            <tr>
                <th>Order ID</th>
                <th>Customer ID</th>
                <th>Employee ID</th>
            </tr>
            </thead>
            <tbody>{items}</tbody>
        </table>
        </div>
    );
};

export default App;
import * as React from 'react';
import { useEffect, useRef, useState } from 'react';
import { DataManager, JsonAdaptor, Query, ReturnOption } from '@syncfusion/ej2-data';
import { data } from './datasource';
import { Row } from './rowTemplate';

interface Changes {
  addedRecords: object[];
  changedRecords: object[];
  deletedRecords: object[];
}

const App: React.FC = () => {
    const [items, setItems] = useState<React.ReactNode[]>([]);
    const dataManagerRef = useRef<DataManager | null>(null);
    const changesRef = useRef<Changes>({
        addedRecords: [],
        changedRecords: [],
        deletedRecords: [],
    });

    useEffect(() => {
        const dm = new DataManager({
            json: data.slice(0, 5),
            adaptor: new JsonAdaptor(),
        });

        dataManagerRef.current = dm;

        dm.executeQuery(new Query()).then((e: ReturnOption) => {
        setItems(
            (e.result as object[]).map((row: any) => (
            <Row key={row.OrderID} {...row} />
            ))
        );
        });
    }, []);

    const action = (e: React.MouseEvent<HTMLInputElement>) => {
        let actionType =
        e.currentTarget.value === 'Update'
            ? 'changedRecords'
            : e.currentTarget.value === 'Insert'
            ? 'addedRecords'
            : 'deletedRecords';

        const orderId = (document.getElementById('OrderID') as HTMLInputElement).value;
        const customerId = (document.getElementById('CustomerID') as HTMLInputElement).value;
        const employeeId = (document.getElementById('EmployeeID') as HTMLInputElement).value;

        if (!orderId) return;

        const rowData = {
        OrderID: +orderId,
        CustomerID: customerId,
        EmployeeID: +employeeId,
        };

        changesRef.current[actionType].push(rowData);

        (document.getElementById('OrderID') as HTMLInputElement).value = '';
        (document.getElementById('CustomerID') as HTMLInputElement).value = '';
        (document.getElementById('EmployeeID') as HTMLInputElement).value = '';
    };

    const saveChanges = () => {
        if (!dataManagerRef.current) return;

        dataManagerRef.current.saveChanges(changesRef.current, 'OrderID');

        dataManagerRef.current.executeQuery(new Query()).then((e: ReturnOption) => {
        setItems(
            (e.result as object[]).map((row: any) => (
            <Row key={row.OrderID} {...row} />
            ))
        );
        });

        changesRef.current = {
            addedRecords: [],
            changedRecords: [],
            deletedRecords: [],
        };
    };

    return (
        <div>
        <div className="e-form">
            <input type="number" id="OrderID" placeholder="Order ID" />
            <input type="text" id="CustomerID" placeholder="Customer ID" />
            <input type="number" id="EmployeeID" placeholder="Employee ID" />
            <input type="button" id="Insert" value="Insert" onClick={action} />
            <input type="button" id="Update" value="Update" onClick={action} />
            <input type="button" id="Remove" value="Remove" onClick={action} />
        </div>

        <div className="e-form">
            <label>Click to Save changes:</label>
            <input type="button" id="Save" value="Save Changes" onClick={saveChanges} />
        </div>

        <table id="datatable" className="e-table">
            <thead>
            <tr>
                <th>Order ID</th>
                <th>Customer ID</th>
                <th>Employee ID</th>
            </tr>
            </thead>
            <tbody>{items}</tbody>
        </table>
        </div>
    );
};

export default App;
import React from 'react';

export const Row = (props) => {
    return (
        <tr>
            <td>{props.OrderID}</td>
            <td>{props.CustomerID}</td>
            <td>{props.EmployeeID}</td>
        </tr>
    );
};
import * as React from 'react';
import { IOrders } from './orders';

export const Row: React.FC<IOrders> = (props) => {
    return (
        <tr>
            <td>{props.OrderID}</td>
            <td>{props.CustomerID}</td>
            <td>{props.EmployeeID}</td>
        </tr>
    );
};