Date Time Issue In Batch Request
Describe the bug I'm encountering an issue with the SAP Cloud SDK when generating a batch request in Node.js. The error occurs specifically when trying to handle a Date field (orderDate) during batch processing. The error message is:
Error during batch request: TypeError: momentInstance.unix is not a function The issue seems to arise from the use of date handling and serialization, as shown in the error trace:
serializeFromMoment (/home/vcap/app/node_modules/@sap-cloud-sdk/odata-v2/dist/de-serializers/converters.js:62:38) To Reproduce Steps to reproduce the behavior:
Set up a Node.js project using the SAP Cloud SDK for OData V2. Create a batch request with a Date field formatted using a custom function like formatToTimestampDate. Send the request to an OData service using the SAP Cloud SDK. Observe the error when processing the orderDate field. Expected behavior The orderDate should be correctly serialized and processed without throwing the momentInstance.unix error, and the batch request should execute successfully.
Screenshots N/A
Used Versions:
Node.js version: v16.13.0 npm version: 8.1.0 SAP Cloud SDK version: 1.59.0 Code Examples The code snippet below is where the error is triggered. The error occurs when setting the orderDate field in the batch request.
const formatToTimestampDate = (date) => {
const dateObj = new Date(date);
const timestamp = dateObj.getTime();
return `\/Date(${timestamp})\/`;
};
const createOrderRequestBuilder = zcssc_C_Order_HeaderApi.requestBuilder().create(
zcssc_C_Order_HeaderApi.entityBuilder().fromJson({
orderDate: formatToTimestampDate(req.data.createdAt),
currency: req.data.currency,
customerName: req.data.customerName,
grossValue: req.data.grossValue.toString(),
guid: req.data.guid,
itemsAddedOnline: req.data.itemsAddedOnline,
orderType: req.data.orderType,
orderTypeDescr: req.data.orderTypeDescription,
salesOrg: req.data.salesOrg,
plant: req.data.storeId
})
);
Log file Here’s the relevant part of the error stack trace:
Error during batch request: TypeError: momentInstance.unix is not a function
at serializeFromMoment (/home/vcap/app/node_modules/@sap-cloud-sdk/odata-v2/dist/de-serializers/converters.js:62:38)
at /home/vcap/app/node_modules/@sap-cloud-sdk/odata-common/dist/de-serializers/default-de-serializers.js:103:20
at /home/vcap/app/node_modules/@sap-cloud-sdk/odata-common/dist/de-serializers/de-serializers.js:28:28
Impact / Priority
Affected development phase: Development Impact: Blocked Timeline: Go-Live is in 1 weeks.
Additional context The issue appears to stem from how the SDK handles the Date field (orderDate). I’ve attempted various methods to format the date, including using the /Date()/ format as shown in the code, but it consistently leads to this issue.
this is complete code
const { zgwCsscSrv } = require('../services/ZGW_CSSC_SRV'); const { changeset, batch } = require('../services/ZGW_CSSC_SRV/BatchRequest');
const formatToTimestampDate = (date) => {
const dateObj = new Date(date);
const timestamp = dateObj.getTime();
return \/Date(${timestamp})\/;
};
module.exports = async (req) => { try { console.log("Starting batch request process...");
// const service = await cds.connect.to('ZGW_CSSC_SRV');
const { zcssc_C_Order_HeaderApi, zcssc_I_Order_ItemApi, zcssc_I_Pay_SplitApi } = zgwCsscSrv();
// Create the header request
const createOrderRequestBuilder = zcssc_C_Order_HeaderApi.requestBuilder().create(
zcssc_C_Order_HeaderApi.entityBuilder().fromJson({
orderDate: formatToTimestampDate(req.data.createdAt),
currency: req.data.currency,
customerName: req.data.customerName,
grossValue: req.data.grossValue.toString(),
guid: req.data.guid,
itemsAddedOnline: req.data.itemsAddedOnline,
orderType: req.data.orderType,
orderTypeDescr: req.data.orderTypeDescription,
salesOrg: req.data.salesOrg,
plant: req.data.storeId
})
);
// Create the order item requests dynamically
const createOrderItemRequests = req.data.orderItems.map((item, i) =>
zcssc_I_Order_ItemApi.requestBuilder().create(
zcssc_I_Order_ItemApi.entityBuilder().fromJson({
material: item.articleNumber,
discountValue: item.discountValue,
forced: item.forced,
giftIndicator: item.isGift,
itemId: (i + 1).toString(),
netValue: item.netValue,
saId: item.salesAssociateId,
saName: item.salesAssociateName,
saNumber: item.salesAssociateNumber
})
)
);
// Create the payment split requests dynamically
const createPaymentSplitRequests = (req.data.paymentSplits || []).map(payment =>
zcssc_I_Pay_SplitApi.requestBuilder().create(
zcssc_I_Pay_SplitApi.entityBuilder().fromJson({
amount: payment.amount,
paymentCode: payment.paymentCode,
paymentDesc: payment.paymentDescription,
saleType: payment.saleType
})
)
);
// Combine the header, order items, and payment splits into a changeset
const batchRequest = batch(
changeset(createOrderRequestBuilder, ...createOrderItemRequests, ...createPaymentSplitRequests)
);
const token = req.headers.authorization?.split(' ')[1];
const batchResponse = await batchRequest.execute({ destinationName: 'DRGUP_2', jwt: token });
console.log("Batch request executed successfully:", batchResponse);
return batchResponse;
} catch (error) {
console.error("Error during batch request:", error);
return req.error({
code: 'BATCH_EXCEPTION',
message: error.message || 'An error occurred while processing the batch request.',
status: 400
});
}
};
Hey @rpathak-max, I think you are using the wrong assumptions on how fromJson works. The docs are not very exact on that, but I think what you want is rather deserialization. Otherwise you would have to pass an instance of moment instead.
Let me know if that helps.
Hi @marikaner, thank you for your reply. can you please guide me with any docs and any sample how can i pass instance of moment because i have tried with moment library but still facing that error. may be you can share some example of it if its possible.
Sure:
const moment = require('moment');
const createOrderRequestBuilder = zcssc_C_Order_HeaderApi.requestBuilder().create(
zcssc_C_Order_HeaderApi.entityBuilder().fromJson({
orderDate: moment(),
// ...
})
);
Is this what you tried?
No i have to pass the order date which i mentioned as request payload so first i passed that date to the moment and then assigned it i a variable then passed it to the orderDate can you please share the example of that like passing the parameter from postman and convert it into the instance. this is the format i am passing from postman "/Date(1603843200000)/"
As I pointed out before, you have two options:
- Use our deserializer for this. I think this is the preferred option in your case.
- Parse the date according to your needs: https://momentjs.com/docs/#/parsing/string-format/ and https://momentjs.com/docs/#/parsing/date/ might be helpful. Please note that the native JS Date object does not have timezone information so it can get lost.
Ok let me try this solution then i will let you know thank you for your support
Hi @rpathak-max , were you able to resolve your issue using @marikaner 's suggestion?
Hello @deekshas8,
I apologize for the delayed response, and I wanted to express my sincere gratitude for your support. I’m pleased to inform you that the issue has been resolved, thanks to your invaluable assistance. I greatly appreciate your patience and guidance throughout this process.
Thank you once again for your support.