SAPUI5 XmlView Show Data from Aggregation Binding Child - odata

I need to get all the ContactEmployees contacts of each BusinessPartners client, in a Table List. Contacts are loaded but I can not show fields
My request https://***/BusinessPartners?$select=ContactEmployees&$skip=0&$top=20
My JSON Result from request "Only Selected ContactEmployees"
{
"#odata.context" : "https://**********$metadata#BusinessPartners",
"value" : [
{
"ContactEmployees" : [
{
"CardCode" : "C000002",
"Name" : "Jose Duran",
"Position" : null,
"Address" : null,
"Phone1" : null,
"Phone2" : null
},
{
"CardCode" : "C000003",
"Name" : "Leo Manuel",
"Position" : null,
"Address" : null,
"Phone1" : null,
"Phone2" : null
}
]
},
{
"ContactEmployees" : [
{
"CardCode" : "C000010",
"Name" : "MILDRED MEJIA",
"Position" : null,
"Address" : null,
"Phone1" : null,
"Phone2" : null
}
]
},
{
"ContactEmployees" : []
},
{
"ContactEmployees" : []
}
],
"#odata.nextLink" : "BusinessPartners?$select=ContactEmployees&$skip=23&$top=5"
}
My Table View
<Table id="idPartnerTable"
growing="true"
growingScrollToLoad="true"
inset="false"
items="{
path: '/BusinessPartners',
parameters:{
$select:'ContactEmployees,CardCode'
},
sorter: {
path: 'CardCode'
}
}">
<columns>
<Column id="carcode">
<Text text="ID" />
</Column>
<Column id="nombre" >
<Text text="Name" />
</Column>
</columns>
<items>
<ColumnListItem
type="Navigation"
press="onPress">
<cells>
<Text text="{ContactEmployees/CardCode} "/>
<Text text="{ContactEmployees/Name} "/>
</cells>
</ColumnListItem>
</items>
</Table>
CONSOLE ERRORS
Failed to drill-down into ('BUSINESSPARTNERS
CODES')/ContactEmployees/Name, invalid segment: Name -
/******/BusinessPartners?$select=ContactEmployees,CardCode&$orderby=CardCode sap.ui.model.odata.v4.lib._Cache
If I change {ContactEmployees/Name} to {ContactEmployees/0/Name} they are shown but only 1 single contact, and I need to bring them all

Use the expand option in order to get the ContactEmployees of each BusinessPartners.
try this :
<Table id="idPartnerTable"
growing="true"
growingScrollToLoad="true"
inset="false"
items="{
path: '/BusinessPartners',
parameters:{
expand:'ContactEmployees'
},
sorter: {
path: 'CardCode'
}
}">
here is plunker it could help you : http://plnkr.co/edit/Q6KqSRk4kk0V81AdCrvQ?p=preview

Related

UI5 using something like .. in bindingpath

I using a oData-Model that returns for .../User a list like that:
[
{
Id: 5
Name: "name",
Desc: "desc",
IsEditable: false,
Items: [
{ itemName: "Name1" },
{ itemName: "Name2" },
{ itemName: "Name3" },
{ itemName: "Name4" }
]
},
...
]
I bind this to my xml view like that:
<View binding="model>/User(5)">
<Text text="model>Name" />
<Text text="model>Desc" />
<List items="{model>Items}" >
<CustomListItem>
<input text="{model>itemName}" editable="{model>../IsEditable}" />
</CustomListItem>
</List>
</View>
So now i would like to disable the input by its parent "IsEditable" proppertie.
How i can make this happen?
To achieve this you have to edit your code like this:
(Relative binding in JSON Models without a "/", absolute with a "/")
<List items="{model>/Items}" >
<CustomListItem>
<Input value="{model>itemName}" editable="{model>/IsEditable}" />
</CustomListItem>

How to Parse Custom (without Key) response in AMP-autosuggest (Rails 5)

Anyone tells me how can I parse my response in AMP-list. In AMP didn't find any solution how to parse own custom API response.
My Code.
<div
class="autosuggest-container hidden"
[class]="(showDropdown && query) ?
'autosuggest-container' :
'autosuggest-container hidden'"
>
<amp-list
class="autosuggest-box"
layout="fixed-height"
height="120"
src="http://lmyadpi.com/api.json?q=a"
id="autosuggest-list"
>
<template type="amp-mustache">
<amp-selector
id="autosuggest-selector"
keyboard-select-mode="focus"
layout="container"
on="
select:
AMP.setState({
query: event.targetOption,
showDropdown: false
}),
autosuggest-list.hide"
>
{{#results}}
<div
class="select-option no-outline"
role="option"
tabindex="0"
on="tap:autosuggest-list.hide"
option="{{.}}"
>{{.}}</div>
{{/results}}
{{^results}}
<div class="select-option {{#query}}empty{{/query}}">
{{#query}}Sorry! We don't ship to your city 😰{{/query}}
</div>
{{/results}}
</amp-selector>
</template>
</amp-list>
</div>
</div>
<amp-state
id="allLocations"
src="http://lmyadpi.com/api.json?q=a"
"emptyAndInitialTemplateJson": [{
"query": "",
[[]]
}]
></amp-state>
My API response :
[[
"1234",
"value2",
""
],
[
"6321123",
"value3",
""
],
[
"43934322",
"value4",
""
],
[
"43660213",
"value5",
""
],
[
"54373228",
"value6",
""
],
[
"410721327",
"value7",
""
]]

SAPUI5 table binditems from expand performed in a bindelement

I am trying a proof of concept in SAPui5 to check the content of a searchfield, bind a result into another field, if i don't have any result i display an error message that has been written in a message field of my odata
so far i succeeded that this way
this.getView().bindElement({
path: "/ExcSet('" + evt.getSource().getValue() + "')",
model: "EXCEPTION",
events: {
dataReceived: function(response) {
if (response.mParameters.data.Message !== '') {
MessageBox.error(response.mParameters.data.Message);
}
}
}
(If someone knows how to do that a better way, because using mParameters is not the best way, it is welcome)
Now, I want to extend my odata call with an expand navigation to display a table of results, by not using another odata call that the one i used already, so here is my code so far :
eanSearch: function(evt) {
var oView = this.getView();
var oTemplate = new ColumnListItem({
cells: [
new Text({
text: "{Volum}"
}),
new Text({
text: "{Voleh}"
})
]
});
this.getView().bindElement({
path: "/ExcSet('" + evt.getSource().getValue() + "')",
model: "EXCEPTION",
parameters: {
expand: "ExcMarmNav"
},
events: {
dataReceived: function(response) {
if (response.mParameters.data.Message !== '') {
MessageBox.error(response.mParameters.data.Message);
}
}
}
});
oView.byId("table").bindItems({
path : '/ExcMarmNav',
template : oTemplate
});
}
The data of the expand is loaded into my response as you can see here
data: {
"ExcSet('5410366897766')": {
"__metadata": {
"id": "http://...:8000/sap/opu/odata/sap/ZEXCEPTION_SRV/ExcSet('5410366897766')",
"uri": "http://...:8000/sap/opu/odata/sap/ZEXCEPTION_SRV/ExcSet('5410366897766')",
"type": "ZEXCEPTION_SRV.Exc"
},
"Matnr": "000000000040000000",
"Ean": "5410366897766",
"Message": "",
"ExcMarmNav": {
"__list": [
"MarmSet(Matnr='40000000',Meinh='EA')"
]
}
},
"MarmSet(Matnr='40000000',Meinh='EA')": {
"__metadata": {
"id": "http://...:8000/sap/opu/odata/sap/ZEXCEPTION_SRV/MarmSet(Matnr='40000000',Meinh='EA')",
"uri": "http://...:8000/sap/opu/odata/sap/ZEXCEPTION_SRV/MarmSet(Matnr='40000000',Meinh='EA')",
"type": "ZEXCEPTION_SRV.Marm"
},
"Matnr": "40000000",
"Meinh": "EA",
"Umrez": "1",
"Umren": "1",
"Eannr": "",
"Ean11": "5410366897766",
"Numtp": "HE",
"Laeng": "20.000",
"Breit": "20.000",
"Hoehe": "10.000",
"Meabm": "CM",
"Volum": "4000.000",
"Voleh": "CCM",
"Brgew": "2.500",
"Gewei": "KG",
"Mesub": "",
"Atinn": "0000000000",
"Mesrt": "00",
"Xfhdw": "",
"Xbeww": "",
"Kzwso": "",
"Msehi": "",
"BflmeMarm": "",
"GtinVariant": "",
"NestFtr": "0",
"MaxStack": 0,
"Capause": "0.000",
"Ty2tq": ""
}
}
But i don't know how to use resultset to bind it into a table, my code above is not working, if someone has an idea of the params to use for my binditems, or if there is another way to do it?
Best regards
Denis
I managed to do the binding of my table using an intermediate JSON Model based on the response of the Odata Model
eanSearch: function(evt) {
var oView = this.getView();
this.getView().bindElement({
path: "/ExcSet('" + evt.getSource().getValue() + "')",
model: "EXCEPTION",
parameters: {
expand: "ExcMarmNav"
},
events: {
dataReceived: function(response) {
if (response.mParameters.data.Message !== '') {
MessageBox.error(response.mParameters.data.Message);
} else {
var model = new JSONModel({
"items": response.mParameters.data.ExcMarmNav
});
oView.setModel(model, "itemModel");
}
}
}
});
And this is the XML view:
<Table id="table" items="{itemModel>/items}">
<columns>
<Column><Label/></Column>
<Column><Label/></Column>
</columns>
<ColumnListItem>
<cells>
<Text text="{itemModel>Volum}"/>
<Text text="{itemModel>Voleh}"/>
</cells>
</ColumnListItem>
</Table>
works fine but I would like to avoid using the intermediate JSON Model and bind directly the array of the response in the table
Ok I managed to find what I needed :)
so the controller:
eanSearch: function(evt) {
var oView = this.getView();
this.getView().bindElement({
path: "/ExcSet('" + evt.getSource().getValue() + "')",
model: "EXCEPTION",
parameters: {
expand: "ExcMarmNav"
},
events: {
dataReceived: function(response) {
if (response.mParameters.data.Message !== '') {
MessageBox.error(response.mParameters.data.Message);
}
}
}
});
}
and the view:
<Table noDataText="No Data" items="{EXCEPTION>ExcMarmNav}">
<columns>
<Column><Label/></Column>
<Column><Label/></Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{EXCEPTION>Volum}"/>
<Text text="{EXCEPTION>Voleh}"/>
</cells>
</ColumnListItem>
</items>
</Table>

Loading OData without Table or List object in SAPUI5

I have 2 weeks looking for an example to understand how the OData works.
I have defined in the Manifest.json my url with the OData service
{
"_version" : "1.7.0",
"sap.app" : {
"id" : "test",
"type" : "application",
"i18n" : "i18n/i18n.properties",
"applicationVersion": {
"version" : "1.0.0"
},
"title" : "{{appTitle}}",
"description" : "{{appDescription}}",
"sourceTemplate": {
"id" : "servicecatalog.connectivityComponent",
"version" : "0.0.0"
},
"dataSources" : {
"Test" : {
"uri" : "/sap/opu/odata/sap/ZMY_SERVICE_SRV/",
"type" : "OData",
"settings" : {
"odataVersion" : "2.0",
"localUri" : "localService/metadata.xml"
}
}
}
}..
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "test.i18n.i18n"
}
},
"Test": {
"type": "sap.ui.model.odata.v2.ODataModel",
"settings": {
"defaultOperationMode": "Server",
"defaultBindingMode": "TwoWay",
"defaultCountMode": "None"
},
"dataSource": "Test"
},
and in my Component.js within the Init method:
init: function() {
// call the base component's init function
UIComponent.prototype.init.apply(this, arguments);
// create the views based on the url/hash
this.getRouter().initialize();
// set the device model
this.setModel(models.createDeviceModel(), "device");
var sServiceUrl = this.getMetadata().getManifestEntry("sap.app").dataSources["Test"].uri;
var oModel = new sap.ui.model.odata.v2.ODataModel(sServiceUrl);
this.setModel(sabModel, "/Test");
sabModel.read(sServiceUrl, "Test");
}
I don´t want to use a Table or a List to load the OData from Backend. I want to load the information "manually" and based on what I got from the Backend, I want to navigate to one or another View.
Debugging the result in the navigator I see the following error: Console
Checking the Error Log I can see: Error Log
If I test the service in Backend works fine: OData Service
I got:
<?xml version="1.0"?><feed xml:base="http://Myserver:8000/sap/opu/odata/sap/ZMY_SERVICE_SRV/"
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<id>http://Myserver:8000/sap/opu/odata/sap/ZMY_SERVICE_SRV/TestSet</id>
<title type="text">TestSet</title>
<updated>2017-10-23T20:37:55Z</updated>
-<author>
<name/>
</author>
<link title="TestSet" rel="self" href="TestSet"/>
-<entry>
<id>http://Myserver:8000/sap/opu/odata/sap/ZMY_SERVICE_SRV/TestSet('1')</id>
<title type="text">TestSet('1')</title>
<updated>2017-10-23T20:37:55Z</updated>
<category scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" term="ZMY_SERVICE_SRV.Test"/>
<link title="Test" rel="self" href="TestSet('1')"/>
-<content type="application/xml">
-<m:properties xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<d:Pernr>1</d:Pernr>
<d:Nachn>TestUser</d:Nachn>
<d:Vorna>UserTest</d:Vorna>
<d:SavingDate m:null="true"/>
<d:Option/>
<d:MsgType/>
<d:MsgNumb/>
</m:properties>
</content>
</entry>
Thank you for your help!!! Any input is more than welcome!!
try this
var oModel = this.getModel("Test");//get the model
oModel.read("/TestSet", {
method: "GET",
success: function(data) {
alert(JSON.stringify(data));
},
error: function() {
}
});
Read the API documentation about "read" method:
https://sapui5.netweaver.ondemand.com/#/api/sap.ui.model.odata.v2.ODataModel
You should not specify the service URL in read method, because it automatically gets concatenated with "sPath", which you pass as a first argument. You should use the name of entityset (is defined in $metadata) you want to read starting with slash "/".

SAPUI5 Two oData Datasources within manifest / descriptor

i'm using SAPUI5 Version gt 1.30 and I try to define the automatic model instantiation of two external services within the manifest.
My first question is, are more than one odata services allowed? Sorry, but i'cant find it out by the documentation.
The default datasource ("") works. But the second datasource ("HLA") not.
If more than once are allowed, please could somebody look for the right definition.
"sap.app":
"dataSources": {
"mainService": {
"uri": "path.xsodata/",
"type": "OData",
"settings": {
"odataVersion": "2.0",
"localUri": "localService/metadata.xml"
}
}
"secondService": {
"uri": "/path.......xsodata/",
"type": "OData",
"settings": {
"annotations": [],
"odataVersion": "2.0",
"localUri": ""
}
}
},
"sap.ui5":
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "....i18n.i18n"
}
},
"": {
"dataSource": "mainService",
"settings": {
"metadataUrlParams": {
"sap-documentation": "heading"
}
}
},
"HLA": {
"dataSource": "secondService",
"settings": {
"metadataUrlParams": {
"sap-documentation": "heading"
}
}
}
}
Thanks a lot!
Not sure if you have solved your problem, but I encountered the same problem today too. And I realise you need to use different notations when binding those two data sources to a control. I'm using XML view btw.
For the default "" model:
<Table id="table" inset="true" items="{/}" >
<columns>
<Column>
<Text text="ID"/>
</Column>
<Column>
<Text text="Name"/>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{id}"/>
<Text text="{name}"/>
</cells>
</ColumnListItem>
</items>
</Table>
For the second model named "Users":
<Table id="userTable" inset="true" items="{Users>/}">
<columns>
<Column>
<Text text="ID"/>
</Column>
<Column>
<Text text="Last Name"/>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{Users>empNumber}"/>
<Text text="{Users>lastName}"/>
</cells>
</ColumnListItem>
</items>
</Table>
It works for me :)
Of course you can have more than one data source, but it is recommended by the fiori guidelines to only use one.
Do you want your address to look like this path.......xsodata/ ?
Also I think you should remove the localUri from the second data source.
Because if there is no metadata document this might throw an arror.
"secondService": {
"uri": "/proxy/service.xsodata",
"type": "oData",
"settings": {
"odataVersion": "2.0"
}
}
What is the output of the debugger? Do you get an error?
Also your oData model should have a type.
"HLA": {
"dataSource": "secondService",
"type": "sap.ui.model.odata.v2.ODataModel"
}

Resources