Why is ODataV4Adaptor sending batch requests with payload like "PATCH null(109) HTTP/1.1"?

By following this doc page:  Adaptors in EJ2 TypeScript DataManager | Syncfusion

I recently have setup a Apache Olingo ODataV4 data service to support Gantt chart

And I was trying to integrate them today. But the gantt chart keeps sending batch requests like the following when i was editing a task's taskname(or text) inline:

Note that the batch request payload shows " PATCH null(101) HTTP/1.1 ", which should be " PATCH Tasks(101) HTTP/1.1 "

This is apparently a frontend setup issue, please help, thanks a lot!

The request and payload:

# error message
fetch.js:78   POST http://localhost:8080/GanttTasksService/DemoService.svc/$batch 400 (Bad Request)

# Request URL
http://localhost:8080/GanttTasksService/DemoService.svc/$batch
Request Method
POST
Status Code
400 Bad Request
Remote Address
[::1]:8080
Referrer Policy
strict-origin-when-cross-origin
# request headers
POST /GanttTasksService/DemoService.svc/$batch HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
Content-Length: 663
Content-Type: multipart/mixed; charset=UTF-8;boundary=batch_88e9fd38-c0f8-4b5b-aedc-ade77d22dad0
Host: localhost:8080
Origin: http://localhost:5173
Prefer: return=representation
Referer: http://localhost:5173/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0
sec-ch-ua: "Not)A;Brand";v="8", "Chromium";v="138", "Microsoft Edge";v="138"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
# request payload
--batch_88e9fd38-c0f8-4b5b-aedc-ade77d22dad0
Content-Type: multipart/mixed; boundary=changeset_7f7c81a3-1f9d-4dea-9fd0-c3cec2319c50

--changeset_7f7c81a3-1f9d-4dea-9fd0-c3cec2319c50
Content-Type: application/http
Content-Transfer-Encoding: binary

PATCH null(101) HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Content-Id: 0
Content-Type: application/json; charset=utf-8

{"TaskID":101,"TaskName":"TestTask13","StartDate":"2025-07-14T08:00:00.000Z","EndDate":"2025-07-11T17:00:00.000Z","Duration":3,"Progress":16,"ParentID":null,"Dependency":""}

--changeset_7f7c81a3-1f9d-4dea-9fd0-c3cec2319c50--
--batch_88e9fd38-c0f8-4b5b-aedc-ade77d22dad0--
# response headers
HTTP/1.1 400 Bad Request
Date: Sat, 12 Jul 2025 12:02:28 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Accept, Authorization, OData-Version, OData-MaxVersion, Prefer
Access-Control-Expose-Headers: OData-Version
Set-Cookie: JSESSIONID=node012qcar2chwatw663nuhshc9s01.node0; Path=/GanttTasksService
Expires: Thu, 01 Jan 1970 00:00:00 GMT
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal
Content-Length: 116
Server: Jetty(9.4.53.v20231009)


App.vue

<script setup>
import { provide } from "vue";
import { GanttComponent as EjsGantt, Edit, Selection, Toolbar } from '@syncfusion/ej2-vue-gantt';
import { DataManager, ODataV4Adaptor, Query } from '@syncfusion/ej2-data';


// https://services.syncfusion.com/vue/production/api/GanttData
// http://localhost:5089/odata/GanttTasks
// Reference:
// 1. https://ej2.syncfusion.com/vue/documentation/gantt/data-binding#remote-data
// 2. https://ej2.syncfusion.com/vue/documentation/gantt/data-binding#odata-v4-adaptor
const dataManager = new DataManager({
  url: 'http://localhost:8080/GanttTasksService/DemoService.svc/Tasks',
  // Use ODataV4Adaptor for true OData v4 support
  adaptor: new ODataV4Adaptor(),
  crossDomain: true,
  // Batch URL should point to service root $batch endpoint
  batchUrl: 'http://localhost:8080/GanttTasksService/DemoService.svc/$batch'
});

// Define task fields mapping
const taskFields = {
  id: 'TaskID',
  name: 'TaskName',
  startDate: 'StartDate',
  duration: 'Duration',
  progress: 'Progress',
  dependency: 'Dependency',
  // Map flat parent reference
  parentID: 'ParentID'
};

// Create query - entity set already specified in URL
const query = new Query();

const editSettings = {
    allowAdding: true,
    allowEditing: true,
    allowDeleting: true,
    allowTaskbarEditing: true,
    showDeleteConfirmDialog: true
};

// Toolbar
const toolbar = [
  'Add',
  'Edit',
  'Delete',
  'Cancel',
  'ExpandAll',
  'CollapseAll',
  'PrevTimeSpan',
  'NextTimeSpan',
  'Update',
  'Indent',
  'Outdent'
];

provide('gantt',  [ Edit, Selection, Toolbar ]);
</script>

<template>
  <div
    style="position:absolute; top:0; right:0; bottom:0; left:0; display:flex; flex-direction:column; overflow:hidden;">
    <!-- Gantt fills remaining space -->
    <div style="flex: 1 1 auto; min-height: 0; overflow:auto;">
      <ejs-gantt
        :taskFields="taskFields"
        :height="'100%'"
        :dataSource="dataManager"
        :query="query"
        :timezone="'UTC'"
        :toolbar="toolbar"
        :editSettings="editSettings"/>
    </div>
  </div>
</template>

<style>
/* Material theme used for this sample */
@import "@syncfusion/ej2-base/styles/material.css";
@import "@syncfusion/ej2-buttons/styles/material.css";
@import "@syncfusion/ej2-calendars/styles/material.css";
@import "@syncfusion/ej2-inputs/styles/material.css";
@import "@syncfusion/ej2-lists/styles/material.css";
@import "@syncfusion/ej2-vue-dropdowns/styles/material.css";
@import "@syncfusion/ej2-navigations/styles/material.css";
@import "@syncfusion/ej2-popups/styles/material.css";
@import "@syncfusion/ej2-splitbuttons/styles/material.css";
@import "@syncfusion/ej2-layouts/styles/material.css";
@import "@syncfusion/ej2-grids/styles/material.css";
@import "@syncfusion/ej2-treegrid/styles/material.css";
@import "@syncfusion/ej2-vue-gantt/styles/material.css";
</style>


main.ts

import { registerLicense } from '@syncfusion/ej2-base';

registerLicense('******');

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'

createApp(App).mount('#app')




3 Replies

SJ Sridharan Jayabalan Syncfusion Team July 16, 2025 02:10 PM UTC

Hi Ryan,

 

We attempted to replicate the issue you described, where the batch request payload shows "PATCH null(101) HTTP/1.1" instead of the expected "PATCH Tasks(101) HTTP/1.1". However, we were unable to reproduce the issue on our end.

We suspect that the issue may be related to the configuration or path of the batchUrl method. To help us investigate further, please provide the following:

  1. The backend controller file: GanttTasksService/DemoService.svc
  2. A video demonstration showing how the issue occurs
  3. Alternatively, you may replicate the issue using the sample provided below or share your runnable back-end sample.

 

Client Sample - Ratwuh5o (duplicated) - StackBlitz

Server Sample - https://www.syncfusion.com/downloads/support/directtrac/general/ze/OdataV4_Server

 

 

 

Regards,

Sridharan



RY Ryan.L replied to Sridharan Jayabalan July 18, 2025 01:30 AM UTC

here's the source code


Attachment: sourcecode_119739ad.zip


SJ Sridharan Jayabalan Syncfusion Team July 22, 2025 01:54 PM UTC

Hi Ryan,

Thank you for sharing your code samples.

 

We have reviewed both the backend and frontend code you provided in your previous response. While we were unable to run the backend sample directly, we noticed that the localhost was still accessible (refer screenshot). Therefore, we used the specified port number to run the client-side application and were able to successfully fetch data using the GET method.

 

We also attempted to perform CRUD operations but were unable to execute them successfully.

 

 

To proceed, we created a separate backend sample based on your controller file. Using this setup, we tested the scenario you reported — specifically, editing the task name in a cell and checking the payload in the network tab. However, we were not able to reproduce the issue on our end.

 

We recommend reviewing our backend implementation and adapting it to your application. This approach may help resolve the issue you're facing.

Back End Sample - https://www.syncfusion.com/downloads/support/directtrac/general/ze/Batch_OdataV4_Crud

Front End Sample - https://stackblitz.com/edit/l8etbz9p-zqynxssr?file=src%2FApp.vue

Documentation - Bind data & perform CRUD action with ODataV4Adaptor in Syncfusion Grid

Video demo - https://www.syncfusion.com/downloads/support/directtrac/general/ze/OdataVideo

Regards,

Sridharan


Loader.
Up arrow icon