cancel
Showing results for 
Search instead for 
Did you mean: 

$Batch request from UI5 application returns "Property 'xyz' is invalid" error from SAP GW

chandan-jha29
Explorer
0 Kudos

Hi,

I have a SAP UI5 table from which I am getting all the rows and creating a JSON which I then pass to the back-end SAP system using oModel.submitChanges in my controller.

I am using oDataModel v2 to accomplish this.

batchSave: function(){
  var items = [];// intializing an array
  var oTable = sap.ui.getCore().byId("JobsDetails");
  var oTableData = oTable.getModel().getData();// getting table data
  var sServiceUrl = "http://example.com:8004/sap/opu/odata/SAP/ZXX_SRV"; // ODATA URL
  var oModel = new sap.ui.model.odata.v2.ODataModel(sServiceUrl, true);
  var aDeferredGroup = oModel.getDeferredGroups().push("myBatch");
  oModel.setDeferredGroups(["myBatch"]);
  var mParameters = {groupId:"myBatch"};           
  for (i = 0; i < oTableData.length; i++) {
   items.push({
       "Jobname": oTableData[i].Job,
       "Jobtext": oTableData[i].JobName,
   });
   //oEntry is the main object to send data using batch operation.
  var oEntry = {
    //converting data into json format
    "JobsData": JSON.parse(JSON.stringify(items)),
  };     
  oModel.create("/MyJobsSet", oEntry, mParameters);
}
oModel.submitChanges(mParameters);
}

The issue is when this method is called, it returns the error: "Property 'JobsData' is invalid" in the browser. JobsData here is the JSON string that we are pushing into oEntry and passing to the oModel. This error appears for oModel.submitChanges(mParameters);

Do I need to have any such property at the Gateway Client side (in SEGW)? or anywhere else? What is wrong in this approach?

Please find the browser response for the error below-

2018-01-17 10:10:40.841722 The following problem occurred: HTTP request failed400,Bad Request,{"error":{"code":"/IWCOR/CX_DS_EP_PROPERTY_ERROR/005056A509B11ED1BF822D2D09171A04","message":{"lang":"en","value":"Property 'JobsData' is invalid"},"innererror":{"application":{"component_id":"CA","service_namespace":"/SAP/","service_id":"ZXX_SRV","service_version":"0001"},"transactionid":"5A5948625F30D406E10000000A5F0E19","timestamp":"20180117044040.5668060","Error_Resolution":{"SAP_Transaction":"Run transaction /IWFND/ERROR_LOG on SAP Gateway hub system and search for entries with the timestamp above for more details","SAP_Note":"See SAP Note 1797736 for error analysis (https://service.sap.com/sap/support/notes/1797736)"},"errordetails":[]}}} - 

Thanks,

Chandan

Accepted Solutions (0)

Answers (2)

Answers (2)

former_member484715
Contributor
0 Kudos

Hi Chandan Jha,

I think your error is in the oEntry object. Could you try by not using double quotes for the key name in the object.

Regards,

Arjun Biswas

chandan-jha29
Explorer
0 Kudos

Thanks for the response Arjun but this did not help. Still receiving the same error.

former_member185414
Active Contributor
0 Kudos

Whatever data you are passing in the payload should exist in the corresponding entity on which you have triggered the HTTP call.

Here in MyJobs entity(assuming MyJobsSet is entityset) you should have all the properties for which you are passing data in payload, for example JobsData.


chandan-jha29
Explorer
0 Kudos

Thanks for the response Ankit.

So, what type should the JobsData be declared with, as it has got multiple fields.

Currently in the above scenario MyJobs entity has these 2 fields Jobname and Jobtext (the JSON that I have created for) of type edm.string that was created from an ABAP Structure with these columns. I actually want to pass data for these fields but in a batch. Is it possible following this approach? or do I need to create some other type of Entity to receive this data?

Regards,

Chandan

former_member185414
Active Contributor
0 Kudos

Apologies for delayed revert. Please paste the JSON payload you want to send to backend and we will advise the modelling.

chandan-jha29
Explorer
0 Kudos

Hi Ankit,

Thanks for your response.

Please find the Final JSON that would go through as a create request.

oEntry
|-_proto_		[Object]
|-JobsData		[[object Object],[object Object]]
	|-_proto_ 	[]
	|-length	2
	|-[0]		[Object]
	   |-_ptoto_
	   |-Jobname	"ZXX1"
	   |-Jobtext	"Some Job Text"
	|-[1]		[Object]
	   |-_ptoto_
	   |-Jobname	"ZXX2"
	   |-Jobtext	"This is Job Text"

This is how the JSON looks. As seen above, oEntry is the variable in which the JSON is stored and passed to the model like-

oModel.create("/MyJobsSet", oEntry, mParameters);

Rest of the code I've already shared in the question.

The request body from the browser looks like below-

--batch_f475-c236-dfe3
Content-Type: multipart/mixed; boundary=changeset_e297-1f4e-a236

--changeset_e297-1f4e-a236
Content-Type: application/http
Content-Transfer-Encoding: binary

POST JobsSet HTTP/1.1
sap-contextid-accept: header
Accept: application/json
x-csrf-token: sov495unWag9C2DMzdPIAA==
Accept-Language: en-US
DataServiceVersion: 2.0
MaxDataServiceVersion: 2.0
sap-cancel-on-close: true
Content-Type: application/json
Content-Length: 59

{"JobsData":[{"Jobname":"ZXX1","Jobtext":"Some Job Text"}]}
--changeset_e297-1f4e-a236
Content-Type: application/http
Content-Transfer-Encoding: binary

POST JobsSet HTTP/1.1
sap-contextid-accept: header
Accept: application/json
x-csrf-token: sov495unWag9C2DMzdPIAA==
Accept-Language: en-US
DataServiceVersion: 2.0
MaxDataServiceVersion: 2.0
sap-cancel-on-close: true
Content-Type: application/json
Content-Length: 107

{"JobsData":[{"Jobname":"ZXX1","Jobtext":"Some Job Text"},{"Jobname":"ZXX2","Jobtext":"This is Job Text"}]}
--changeset_e297-1f4e-a236

--batch_f475-c236-dfe3

Note: The data has been modified to maintain client/organization confidentiality.

MyJobs Entity type is created using a DDIC structure and has the following structure-

Jobname - Edm.String

Jobtext - Edm.String

And the Entity Set is MyJobsSet.

Shall you need any further information to help, pls. let me know. Any help would be highly appreciated.

Thanks,

Chandan

former_member185414
Active Contributor
0 Kudos

1. What I see from payload is you are not clearing the data of first object while passing the next time.

First time call - {"JobsData":[{"Jobname":"ZXX1","Jobtext":"Some Job Text"}]}

Next Call - {"JobsData":[{"Jobname":"ZXX1","Jobtext":"Some Job Text"},{"Jobname":"ZXX2","Jobtext":"This is Job Text"}]}

Underlined is the old data.

2. You are triggering a call on JobsSet while your entity set name is MyJobsSet. Both should be same.

3. You have two options of creating multiple jobs in one call

a. Either pass the individual data records in every post request and utilize the create method

b. Model another parent entity wich will store multiple job data records and utilize a deep creata method.

4. I advise use 3 b. Create another wrapper entity and pass all jobs data records together.

search SCN for deep create example.

chandan-jha29
Explorer
0 Kudos

Hi Ankit,

My responses inline with your points -

1. How do I clear it? Shall I clear the var oEntry after every iteration of oModel.create? Or should I do the oModel.create only once outside the for loop?

2. This has been taken care of. Using the right entity set name.

3/4. As you suggested, I will go with 3b. If you have any good example of this handy then pls. suggest else I will do the search.

Thanks a ton for helping out.

Chandan

former_member185414
Active Contributor

1. This should be outside for loop

  var oEntry ={//converting datainto json format"JobsData": JSON.parse(JSON.stringify(items)),};     
  oModel.create("/MyJobsSet", oEntry, mParameters);

3/4. UI5 sample - https://blogs.sap.com/2012/11/18/gateway-batch-calls-from-sapui5/

backend sample - https://blogs.sap.com/2014/04/27/step-by-step-development-guide-for-createdeepentity-operation/

PS: These are samples which I got from google and there are many more available.