SAPUI5 oModel.create() - how to post data to the SAP backend? - post

I got a button where I want to post data to my SAP backend on press-method:
oCellBtnOtherchart.addContent(new sap.ui.commons.Button({
text : "Save",
press : function() {
var sServiceUrl = "/MyEntitSet('0001')";
var oModel = sap.ui.getCore().getModel();
console.log(oModel);
var oParameters = {
"email" : "a",
"lastname" : "b",
"firstname" : "c",
};
oModel.create(sServiceUrl, oParameters);
}
}));
My questions are:
In which method would this request end in backend? I expect MyEntitySet_CREATE_ENTITY()
Why doesnt it work, the error message is: HTTP request failed 405, Method Not Allowed
But why is it 405, is my Service URL Wrong? How do I Post data correctly to the SAP Backend?
SAP Troubleshooting Guide says: 405 Method Not Allowed
o The method specified in the Request-Line is not allowed for the resource
identified by the Request-URI. The response must include an Allow header
containing a list of valid methods for the requested resource. --> This does not help me right now, anybody knows how to include an allow header?

Because there are only few threads on this topic at SO, which in my opinion do not answer the questions I had, I'll share my findings how to pass data to the backend via oModels create method:
First Define a type of your result entity (check your oData-Model to know the attributes, e.g. Name and YourID):
var oEntry = {};
oEntry.YourID = "0001";
oEntry.Name = "Peter";
Then fetch your model:
var oModel = sap.ui.getCore().getModel();
Then execute the create operation thanks to: https://sapui5.netweaver.ondemand.com/docs/api/symbols/sap.ui.model.odata.ODataModel.html
jQuery.sap.require("sap.ui.commons.MessageBox");
oModel.create('/EntitySet', oEntry, null, function(){
sap.ui.commons.MessageBox.show(
sap.ui.commons.MessageBox.alert("Success!");
);
},function(){
sap.ui.commons.MessageBox.alert("Error!");
});
Results in Backend in Method "ENTITYSET_CREATE_ENTITY"-Method, where you can retrieve YourID and Name:
DATA: ls_data TYPE ycl_class_mpc=>ts_entity.
CALL METHOD io_data_provider->read_entry_data
IMPORTING
es_data = ls_data.
WRITE ls_data-name.
WRITE ls_data-yourid.
This example applies to single calls, you can see the result in ABAP is a structure. If you need to pass multiple datasets to the backend you should search for batch processing at https://openui5.hana.ondemand.com/docs/api/symbols/sap.ui.model.odata.ODataModel.html

If you are still looking for a good blog on how to make a batch post then have a look at this post http://scn.sap.com/community/developer-center/front-end/blog/2012/11/18/gateway-batch-calls-from-sapui5

Related

Data Gets Converted when passed to CREATE_STREAM

I have created an UI5 Application to read a file and send it to a custom OData Service in the Backend.
onUploadFile: function() {
var oFileUpload =
this.getView().byId("fileUploaderFS");
var domRef = oFileUpload.getFocusDomRef();
var file = domRef.files[0];
var that = this;
var reader = new FileReader();
var ftype = file.type;
reader.readAsArrayBuffer(file);
reader.onload = function(evt) {
var vContent = evt.currentTarget.result
console.log(vContent);
var hex = that.buf2hex(vContent);
that.updateFile(hex, ftype);
}
},
buf2hex: function(buffer) {
return [...new Uint8Array(buffer)]
.map(x => x.toString(16).padStart(2, '0'))
.join('');
}
When I print the content of hex on the console before sending it to the backend, the data starts with 89504e470d0a1a0a0000000d49484 ....
Even before sending the data in the payload to Odata Service it shows the correct data
Here is the Odata Service
Inside the Create Stream the data when received, is getting converted into something else. As a result the image that has been saved is not opening.
I tried to change the Data Type of Content in SEGW to Binary and it did not work. I also tried to convert the data in the create_stream but in vain. At last I tried reading the data in UI5 in different formats but of no use.
This whole Odata service works perfectly fine when I load the data through Postman Application.
Please help me resolve this Issue. Thanks In Advance.
The sap.ui.unified.FileUploader has everything built in. No need for conversions from Buffer to hex.
Make sure that your FileUploader knows where to upload the file
<unified:FileUploader xmlns:unified="sap.ui.unified"
id="fileUploaderFS"
uploadUrl="/sap/opu/odata/sap/Z_TEST_SRV/FileSet"
/>
The attribute uploadUrl points to the media entity for which you implemented the create_stream method.
Then when the upload is triggered via button press, simply get the FileUploader, set the token (for security reasons when doing a POST request), and fire the upload method.
onUploadFile: function () {
const oFileUpload = this.getView().byId("fileUploaderFS");
const sToken = this.getModel("nameOfTheModel").getSecurityToken();
const oTokenParam = new FileUploaderParameter({
name: "x-csrf-token",
value: sToken
});
oFileUpload.removeAllHeaderParameters()
oFileUpload.addHeaderParameter(oTokenParam);
oFileUpload.upload();
}
To use FileUploaderParameter, make sure to import it at the beginning:
sap.ui.define([
// ...,
"sap/ui/unified/FileUploaderParameter"
], function (/*..., */FileUploaderParameter) {
// ...
Now about your File entity. When working with it via create_stream or read_stream, you don't use the entity structure but is_media_resource. This means your entity doesn't need a property content. Or most of the other properties (except a unique id and the mime type). All other properties would only be used if you want to do one of the CRUD methods (which happens almost never when dealing with streams).

How can I pass filter parameter in OData read method [duplicate]

This question already has answers here:
Why my filter is not working in v2.ODataModel "read"?
(3 answers)
Closed 18 days ago.
I need to pass a parameter in my OData.
The URL has to be like this:
http://my_gateway_system:port/sap/opu/odata/sap/ZGW_TRANSF_APPROVAL_SRV_02/ztest_nameset('RUBENS')
Below is my code:
var sServiceUrl = "http://<my_gateway_system>:<port>/sap/opu/odata/sap/ZGW_TRANSF";
var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, true, "username", "password");
var oJsonModel = new sap.ui.model.json.JSONModel();
oModel.read("/ztest_nameset('RUBENS')", null, null, true, function(oData, response) {
oJsonModel.setData(oData);
});
sap.ui.getCore().setModel(oJsonModel);
When I past the URL
http:// my_gateway_system:port/sap/opu/odata/sap/ZGW_TRANSF_APPROVAL_SRV_02/ztest_nameset('RUBENS')
in my browser, it works. But when I run my code, it's not working.
You are using the legacy method call of ODataModel#read (with the parameters spread out). The current signature for this method is read(sPath, mParameters). Please check out the documentation of the method: https://openui5.hana.ondemand.com/#docs/api/symbols/sap.ui.model.odata.ODataModel.html#read
In your concrete case, you should do something like:
oModel.read("/ztest_nameset('RUBENS')", {
filters: [/* your filters here */],
success: function(oData) {
oJsonModel.setData(oData);
}
});
Nevertheless, it is not clear what filter parameter you want to pass. In your example, you have no filter. The /ztest_nameset('RUBENS') URI is just a plain entity set + key. It is also not clear what errors you get. I could guess that it can be a CORS issue. You seem to be making the OData calls to some other host than the one you are serving the UI5 app from.

OData : Why am I getting HTTP 428 (Precondition Required) error while performing an update

So here's my code
sap.ui.getCore().getModel("myModel").update("/ZSystemNameSet(mandt='001')", data, null, function(datay, responsey){
sap.ui.getCore().getModel().refresh();
MessageToast.show("It worked...!! Data: "+datay+"Response: "+responsey);
}, function(datax,responsex){
MessageToast.show("Sorry! Data: "+datax+"Response: "+responsex);
});
Also how do I add the header attributes to the update() call?
Obviously your service uses optimistic locking and expects an If-Match header, containing the ETag of the entity, in the request. You can pass this ETag as parameter to the update method. For further details you should check your service definition and the documentation.
Regarding the update of header attributes: It is hard do answer as there is no information regarding your entity orchestration. Normally you should be able to add a property containing the update information for you header to the data structure you send to the server, e.g. if the header is reachable from your entity ZSystemName via association "Header" you do the following:
data.Header = { "attribute1" : value1, "attribute2" : value2 }

Create New Row in database using Odata

I have an OData Service that is pointing to a table in the database. I want to enter a new record in the table based on the details from user.
I am using the .create method, but the data doesn't seem to get entered in table.
oView=this.getView();
var df = {};
var name = oView.byId("__input3").getValue();
var goal = oView.byId("__area0").getValue();
df.NAME = name;
df.GOAL = goal;
df.TYPE = "type";
df.THEME = "Theme";
var oModel1= new sap.ui.model.odata.ODataModel("/GDH_OData/services/df.xsodata/");
oModel1.create('/Df', df, null, function() {
alert("SUCCESS");
}, function() {
alert("FAIL");
});
Please help where I am going wrong
you're not giving a lot of info, here...
what is the result of your create call ? SUCCESS or FAIL ? if the later, what is the error message returned ? the following error function can help you on this
function(error) {
var message = $(error.response.body).find('message').first().text();
console.log(message);
alert(message);
}
Is the creation code in the backend called (if you put an external breakpoint in your service, do you get the debugger ?) if so, what is the result of debugging step-by-step ?
edit
if there is a "forbidden" response, then you should check the result of transaction su53 for the user. You'll probably have a failed autorization. Then it's just adding the service to your role autorisation.
PS : its better to add your answer to my questions(s) in your question, under a "edit" or "more information" than to put it as another answer. Thus there is only one place to check for the whole problem.
regards
The result is Fail and the error is "Failed to load resource: the server responded with a status of 403 (Forbidden)"

Unexpected exception upon serializing continuation

I get this error: Unexpected exception upon serializing continuation (not much help)
It is caused by the FetchUrlApp.fetch(); call. I akm using Google Apps Script for Sites, not Google Spreadsheets. The code works in the original instance but as soon as I copy and paste the code into a new project I get the above error message. I am accessing Google Docs APIs. I have read on other forums that I need authorization but I have been unable to gain the right authorization for the code to work. No prompt ever pops up when I run a copy of the code for the first time.
Code exert:
var oauthConfig = UrlFetchApp.addOAuthService("docs");
oauthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oauthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope=https://docs.google.com/feeds/");
oauthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oauthConfig.setConsumerKey(_consumerKey_);
oauthConfig.setConsumerSecret(_consumerSecret_);
var requestData3 = {
"method": "GET",
"headers": {"GData-Version": "3.0"},
"oAuthServiceName": "docs",
"oAuthUseToken": "always",
};
var url = "https://docs.google.com/feeds/" + userName + "/private/full/-/mine";
var result = UrlFetchApp.fetch(url, requestData3); //error occurs, any thoughts?
Thank you in advance,
James Krimm
You have to set both consumerKey and consumerSecret to "anonymous" in order to trigger the 3-legged OAuth process:
oauthConfig.setConsumerKey("anonymous");
oauthConfig.setConsumerSecret("anonymous");
Replace your two lines with these and the authorization popup dialog will show up, allowing the user to grant access to its documents.
What I would suggest is to write a special function that does nothing else than call the Oauth process and call it from the script editor once.
As an example, here is the one I have used recently to make the authorize popup appear :
function authorize(){
// function to call from the script editor to authorize googleOauth
var id=mailtemplatedoc
var url = 'https://docs.google.com/feeds/';
var doc = UrlFetchApp.fetch(url+'download/documents/Export? exportFormat=html&format=html&id='+id,
googleOAuth_('docs',url)).getContentText();
}
EDIT : And the missing part I had forgotten :
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey('anonymous');
oAuthConfig.setConsumerSecret('anonymous');
return {oAuthServiceName:name, oAuthUseToken:"always"};
}

Resources