SAPUI5 ODataModel metadata $format=xml - odata

i am trying to connect sapui5/openui5 ODataModel to an odata-server. I want to use a nodejs server with package simple-odata-server. Unfortunately this odata server provides metadata only in xml-format. But sapui5 tries to load metadata in json-format.
Before i switch to another odata server, i want to check, wether sapui5 can load metadata in xml-format. I tried to create the model with several parameters, but ODataModel still tries to load metadata as json.
var oModel = new ODataModel("/odata", {
"metadataUrlParams": "$format=xml",
"json": false
});
Does anybody know, wether i can switch to $format=xml
Thanks in advance,
Torsten

As far as I know the OData protocol metadata is always provided as XML, never seen metadata in JSON format. Also my n-odata-server Qualiture mentioned in the comment above does it. But I never had problems with SAPUI5. It requests the metadata, gets the xml stream and works with it.

Since the metadataUrlParams parameter is of type map I'd suppose it would at least do what you intend like this:
var oModel = new ODataModel("/odata", {
"metadataUrlParams": {
"$format": "xml"
}
});
https://sapui5.hana.ondemand.com/sdk/#docs/api/symbols/sap.ui.model.odata.ODataModel.html#constructor

Related

Get Response from CREATE_STREAM

We upload a document from SAPUI5 to our SAP System using the CREATE_STREAM Method of the oData Service in ABAP. The creation of the document works fine.
What we would like to achieve is to get the response back to SAPUI5. Especially when there is an error during the creation of the document in the backend.
In Frontend we use the uploadSet Control.
...oUploadSet.uploadItem(oItem);
In the Backend we create a message with
...lo_message_container->add_message( iv_msg_type = /iwbep/cl_cos_logger=>error
iv_msg_number = '018'
iv_msg_id = lv_msg_id
iv_add_to_response_header = abap_true
)....
We can find the created message in the error protocol of our gateway server (/IWFND/ERROR_LOG). But how can this message be retrieved in SAPUI5 and used in the MessageManger Control?
We tried the onUploadCompleted Control but we can't find any response data there.
Can somebody explain how the response or a message header from the CREAT_STREAM method can be used in SAPUI5?
The "new" UploadSet control is kinda half-baked imo. The response will get lost in some internal method. This internal method will then trigger onUploadCompleted and you get nothing but useless information.
Lucky for us we can easily overwrite this internal stuff. UploadSet has an aggregation Uploader. We have to provide our own Uploader. Problem solved. Here is the line that needs to be modified.
sap.ui.define([
"sap/m/upload/Uploader",
...
], function (Uploader, ...) {
return Uploader.extend("my.custom.control.Uploader", {
uploadItem: function (oItem, aHeaders) {
// beginning of the method. take it from the official sources
oXhr.onreadystatechange = function () {
const oHandler = that._mRequestHandlers[oItem.getId()];
if (this.readyState === window.XMLHttpRequest.DONE && !oHandler.aborted) {
// we need to return the xhr object. it contains the response!
that.fireUploadCompleted({ item: oItem, xhr: oXhr });
}
};
// .. rest of the method
}
});
});
Use it like this
<mvc:View xmlns:custom="my.custom.control" ....>
<UploadSet items="....">
.....
<uploader>
<custom:Uploader uploadUrl="......"
uploadCompleted=".onUploadCompleted"
uploadStarted=".onUploadStarted" />
</uploader>
</UploadSet>
Edit: Your own uploader also means implementing your own event handlers (uploadAborted, uploadCompleted, uploadProgressed, uploadStarted). See the official documentation for more information about the events.

get 'undefined' saveResult.entities after saveChanges [breezejs]

I tried to update one entity in my angularjs client using breezejs library. After calling saveChanges(), it can actually save back in the server and fetched on the client. However, the server did not return the response back. The saveResult.entities is undefined and pop up an error for me. When I took a look at the docs, it mentions 'Some service APIs do not return information about every saved entity. If your server doesn't return such information, you should add the pre-save, cached entity to saveResult.entities yourself'. Could anyone provide an example of how to do this?
This is the code when i am trying to do an update.
manager.saveChanges(entitiesToSave, null, (saveResult) => {
const savedRes = saveResult;
savedRes.entities = entitiesToSave;
return savedRes;
}).then(saveSucceeded);
On the server, you would need to construct the response for an update similar to the way it is for a create:
response.setContent(...); // entities
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());

WebApi Odata: remove metadata from response

I'm developing an WebApi Odata service for internal usage. I want to remove from response at server all additional data except serialized data.
I want to remove all this stuff:
{
"#odata.context":"http://192.168.150.86:9933/odata/$metadata#Terminal","value":[
]
}
and leave here only array of "Terminal"
is there any way to do this?
Add the following option to your query string:
$format=application/json;odata.metadata=none
This will remove the odata metadata from your results.
This is how it can be accomplished.
var ODataJSON = JsonConvert.DeserializeObject<JObject>(json);
ODataJSON.Property("#odata.context").Remove();
ODataJSON.Add("Terminal", ODataJSON["value"]); //adding Terminal attribute
ODataJSON.Property("value").Remove(); // removing default value attribute.
You can also set the Accept header
Accept: application/json;odata.metadata=none
Let's assume that you are writing a new function that returns IHttpActionResult. To return the data you can use the Json method. It removes the metadata

BreezeJS/Odata - metadata location/url

In our odata service implementation, the autogenerated metadata can be accessed at:
https://<ourserver>/v1/$metadata
But the BreezeJS tries to access it from https://<ourserver>/v1/Metadata. And it gets a 404 error as the metadata is not served at this location.
How to instruct BreezeJs to find the metadata at any given URL?
The code entityManger.fetchMetadata() is trying reach metadata at https://<ourserver>/v1/Metadata and not at where it is available https://<ourserver>/v1/$metadata
You need to tell Breeze that you are using OData, by default it assumes WebApi. So:
breeze.config.initializeAdapterInstances({ dataService: "OData" });
Also see: http://www.breezejs.com/documentation/odata

How can I get Breeze to query $metadata instead of Metadata?

I set up my odata service with Node, MongoDB and JayData. When I hit http://localhost:8000/odata/findash.svc/$metadata in my browser I get the metadata exactly as I would expect.
In the browser console I execute this sample code:
var manager = new breeze.EntityManager('odata/findash.svc');
var query = new breeze.EntityQuery()
.from("accounts");
manager.executeQuery(query).then(function(data){
console.log(data);
}).fail(function(e) {
alert(e);
});
An alert pops up with the message: Error: Metadata query failed for: odata/findash.svc/Metadata; Not Found
The net tab confirms that Breeze is hitting odata/findash.svc/Metadata which produces a 404 instead of odata/findash.svc/$metadata which works fine.
Is there a way to configure this behavior in Breeze or is the problem with my odata setup?
I assume that you meant OData and not JayData in your question. Breeze and JayData are two different products. If not then I'm not sure I understand the question.
I think that you haven't told breeze to use the OData endpoint. By default breeze uses a WebApi endpoint. You can change this via the breeze.config like this:
breeze.config.initializeAdapterInstances({
dataService: "OData", ...
});
Breeze supports both OData and a WebApi endpoints. The OData endpoint ( per the OData spec) returns metadata from '$metadata". The webApi endpoint returns metadata from 'Metadata'.
See: http://www.breezejs.com/documentation/odata

Resources