I recently had to fetch a complete structure of an entity in my OData service to get the labels and attribute type like Edm.DateTime etc. Please note that this tutorial only has been tested with an OData V2 service.
This allows you to works with large entities for example to handle an Excel export function, where you have to provide the exact columns, you want to export. It saves you a lot of time, when you have like 100 columns in one entity, which are all may relevant for this type of export.
/**
* Returns the properties of an entity with its metadata.
* @param {object} oModel The model object, for example the oData service.
* @param {string} sEntityName The name of the entity, which should be fetched in a structure.
* @returns {object} An object where the keys are the field names and the metadata is inside.
*/
fetchStructureMeta: function (oModel, sEntityName) {
const oMetadata = oModel.getServiceMetadata();
let oEntity;
for (let oCEntity of oMetadata.dataServices.schema[0].entityType) {
if (oCEntity.name === sEntityName) {
oEntity = oCEntity;
break;
}
}
if (oEntity) {
let oStructure = {};
let i = 0;
for (let oCProperty of oEntity.property) {
oStructure[oCProperty.name] = {
...oCProperty,
index: i
};
i++;
}
return oStructure;
} else {
// Entity not found in the service.
return false;
}
},
As you can see, we can pass here our model to the function, as well as the entity name, which we later want the structure from. Then the entity should be found via the .getServiceMetadata() function from the model.
Then we can read out here the details about the entity and we add additionally an index, which is for example necessary for the export function.
Test case
For a quick example I have integrated the Northwind OData service into my Fiori application and I want to fetch here the properties from the customer. For that I have included the service as a default model.
If we checkout the $metadata file of the Northwind service, we found here some properties in the customer entity:
In our Fiori application, I have added just the following snippet into my default controller to test out the functionality. Since the metadata has may a bit longer to load, I have added also a 2 seconds timeout in the snippet to ensure, that this has been loaded until then.
onAfterRendering: function () {
setTimeout(() => {
const oMetadata = this.fetchStructureMeta(this.getView().getModel(), "Customer");
console.log(oMetadata); // View in the console
console.log(JSON.stringify(oMetadata)); // To show it later here in the post
}, 2000);
},
Result
For the result, you will now fetch for each property in the entity a key, which you can use to access later the metadata.
{
"CustomerID": {
"name": "CustomerID",
"type": "Edm.String",
"nullable": "false",
"maxLength": "5",
"fixedLength": "true",
"unicode": "true",
"index": 0
},
"CompanyName": {
"name": "CompanyName",
"type": "Edm.String",
"nullable": "false",
"maxLength": "40",
"fixedLength": "false",
"unicode": "true",
"index": 1
},
"ContactName": {
"name": "ContactName",
"type": "Edm.String",
"maxLength": "30",
"fixedLength": "false",
"unicode": "true",
"index": 2
},
"ContactTitle": {
"name": "ContactTitle",
"type": "Edm.String",
"maxLength": "30",
"fixedLength": "false",
"unicode": "true",
"index": 3
},
"Address": {
"name": "Address",
"type": "Edm.String",
"maxLength": "60",
"fixedLength": "false",
"unicode": "true",
"index": 4
},
"City": {
"name": "City",
"type": "Edm.String",
"maxLength": "15",
"fixedLength": "false",
"unicode": "true",
"index": 5
},
"Region": {
"name": "Region",
"type": "Edm.String",
"maxLength": "15",
"fixedLength": "false",
"unicode": "true",
"index": 6
},
"PostalCode": {
"name": "PostalCode",
"type": "Edm.String",
"maxLength": "10",
"fixedLength": "false",
"unicode": "true",
"index": 7
},
"Country": {
"name": "Country",
"type": "Edm.String",
"maxLength": "15",
"fixedLength": "false",
"unicode": "true",
"index": 8
},
"Phone": {
"name": "Phone",
"type": "Edm.String",
"maxLength": "24",
"fixedLength": "false",
"unicode": "true",
"index": 9
},
"Fax": {
"name": "Fax",
"type": "Edm.String",
"maxLength": "24",
"fixedLength": "false",
"unicode": "true",
"index": 10
}
}
Foto von Ferenc Almasi auf Unsplash
Leave a Reply