on 2020 Jan 24 10:00 AM
Hello,
I am currently working on an application using CAP & Node.js. The application is basically a service that aggregates data from existing standard SAP APIs, and a Fiori Elements front-end (List Report & Object Page).
To be able to aggregate the data of the APIs, I use a custom service implementation in Javascript, with the event handlers (before, on, after).
My problem is that I am not able to re-implement the OData V4 $count query (in the custom handlers), that is necessary to have the Fiori Elements list report to work. Apparently the custom handlers "overwrite" the standard $count handler ? Therefore, the List Report issues the following request:
READ Entity {
'$count': 'true',
'$select': '...',
'$skip': '0',
'$top': '30'
}
But gets the following answer:
"@odata.context": "$metadata#Entity",
"@odata.metadataEtag": "...",
"@odata.count": 0,
"value": [
{ ... }, { ... }, ...
]
Since the @odata.count value is 0, the List Report does not display any data. I did not find any way to set this value in the custom handlers, since it seems that I only have access to the "value" array.
So my question is: Is there a way to set a custom value for the results array and still have the standard OData handlers work ?
My question is specifically for the $count query, but I would also like to avoid re-coding the $filter and $sort logic if possible.
Here is a sample of my current implementation:
srv.on('READ', 'Entity', async (req) => {
const queryOptions = req._.odataReq.getQueryOptions() || {};
const [data1, data2, data3] = await Promise.all([
srv.run(SELECT.from('Entity1')),
srv.run(SELECT.from('Entity2')),
srv.run(SELECT.from('Entity3')),
]);
const elements = [...data1, ...data2, ...data3]
.map((el) => ({ Prop1: el.Prop1, Prop2: el.Prop2, Prop3: el.Prop3 }));
const reqData = req.data;
if (reqData && reqData.Prop1 && reqData.Prop3) {
const element = elements.find((el) => el.Prop1 === reqData.Prop1 && el.Prop3 === reqData.Prop3);
return element;
}
const top = queryOptions.$top || flows.length;
const skip = queryOptions.$skip || 0;
return elements.slice(skip, (skip + top <= elements.length ? skip + top : elements.length));
});
srv.after('READ', 'Entity', async (results, req) => {
const queryOptions = req._.odataReq.getQueryOptions();
if (queryOptions && queryOptions.$expand) {
if (!Object.keys(req.data).length) {
req.reject(501, 'Not implemented');
} else if (results.length) {
const el = results[0];
const items = await srv.run(SELECT.from('EntityItems').where({ Entity_Prop1: el.Prop1, Entity_Prop3: el.Prop3 }));
el.Items = items;
}
}
});
srv.on('READ', ['Entity1', 'Entity2', 'Entity3'], async (req) => {
// Handling with request to external API
}):
Thanks for your help,
Theo
I have implemented the same kind of scenario. Wherein, In the service implementation, I read the data on SRV.ON event. However, in the List report, I have search and filter on some fields. They are not working. How can I implement search and filter manually in the custom handlers?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
71 | |
10 | |
8 | |
7 | |
7 | |
6 | |
6 | |
6 | |
6 | |
5 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.