on 02-18-2020 12:29 PM
Hello CAP Enthusiasts,
During my local testing I ran into a strange issue using the Fiori Elements front-end.
I've added a virtual spotsAvalaible property to my entity Courses. This virtual property I'm going to fill in the after hook of the READ of the Courses:
srv.after('READ', 'Courses', (courses, req) => {
// problem from fiori: couses has counted object --> $count
return courses
.map(async course => {
// Get the reservations for this course
const reservations = await cds.transaction(req).run(
SELECT.from(Reservations).where({course_ID: course.ID})
)
// Caluclate spots taken
const spotsTaken = reservations.reduce((total, reservation) => total + reservation.quantity, 0)
course.spotsAvailable = course.spots - spotsTaken
})
})
This works when I use postman and do a get on the courses. (http://localhost:4004/training/Courses)
{
"@odata.context": "$metadata#Courses",
"@odata.metadataEtag": "W/\"BmT9sdj4fnWqz4BxxDN0o+XSNGD5CW69Y8wbhe1uRYk=\"",
"value": [
{
"ID": "ee0b3d38-729d-4237-a7fe-b922f753e87e",
"modifiedAt": null,
"createdAt": "2020-01-18T18:45:57Z",
"createdBy": "anonymous",
"modifiedBy": null,
"title": "Some course",
"days": 1,
"spots": 15,
"courseType": "Technical",
"spotsAvailable": 15,
"trainer_ID": "880331ae-ae41-4a46-b49b-b7a3cbd049b0"
}
]
}
But when using the Fiori elements front-end the hook crashes with following error. For the following request in the $batch:
GET Courses?$count=true&$select=ID,days,spots,title,trainer_ID&$expand=trainer($select=ID,name)&$skip=0&$top=30 HTTP/1.1
POST /training/$batch
READ Courses {'$count': 'true','$select': 'ID,days,spots,title,trainer_ID','$expand': 'trainer($select=ID,name)','$skip': '0','$top': '30'}READ Courses {'$count': 'true','$select': 'ID,days,spots,title,trainer_ID','$expand': 'trainer($select=ID,name)','$skip': '0','$top': '30'}[2020-01-19T14:45:18.101Z | ERROR | 1221510]: Cannot read property 'run' of undefinedTypeError: Cannot read property 'run' of undefinedat C:\repo\CAP\training-reservations\node_modules@sap\cds-services\lib\connect\Transaction.js:84:27
When debugging i notice that the after-hook gets called a second time, but this time the courses-parameter is filled with a counted object:
[{counted: 1}]
I have logged the same issue on the cap-community: https://github.com/sapmentors/cap-community/issues/32
Is there a way to solve this?
Thanks!
Kind regards,
Robin
Hi Robin,
Yes, you need to manually check that in your after handler.
Something like this:
if (req.query.SELECT.columns.filter(({ func }) => func === 'count').length) return
Best regards,
David
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi David,
Sorry for the delay in my answer. But when I add the return statement in the after-handler I still receive the same error. It looks like the method _matchHandlers of the After.js file has an undefined promise for the count-call.
When the call for the actual entity is handled everything is ok.
But when the count call is handled fnReturn is undefined...
And then he seems to get confused and throw the error.
Any idea what might be causing this?
Thanks.
Regards, Robin
Hi Robin,
Whenever you request a count on an entity collection, we trigger two read requests.
The first one works in your example. The second one fails.
To work around this problem, you need to prevent your after handler from running if it is the count request (i.e. the req.query object only selects `count(*)` as a column).
Best regards,
David
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello David,
Thanks for your answer. But how do I prevent the after handler from running if it is a count request?
Do I need to add a check inside the after handler to check if it is a count-request or is there another way of solving this?
I don't see anything regarding this topic in the documentation.
Thanks,
Kind regards,
Robin
User | Count |
---|---|
69 | |
9 | |
8 | |
6 | |
6 | |
6 | |
6 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.