cancel
Showing results for 
Search instead for 
Did you mean: 

How can I implement $count=true support with an external OData v2 service in CAP?

pieterjanssens
Active Participant
0 Kudos

Running the Fiori preview on an entity which is being served from an external OData v2 service the page shows the error 'Feature not supported: Method .count of fluent API'. Is there a way this can be resolved in the service implementation?

This would support $filter in the query (and therefore is not the solution I'm after), but for testing purposes I tried checking for req.query.cqn.count being true and then executing an explicit OData v2 $count request:

return await ext.tx(req).get("/User/$count")

This does get the count, but returning a number in the service implementation then results in the following error:

[2020-07-06T19:41:42.970Z | ERROR | 1773773]: An error occurred during serialization of the entity collection.
OlenaT
Advisor
Advisor
0 Kudos

Hi Pieter,

could you please check this question https://answers.sap.com/questions/13080251/cap-custom-handler-inline-count.html and let me know if it provides any useful information for you?

Best regards,

Olena

pieterjanssens
Active Participant
0 Kudos

Hi Olena,

Thanks, it sure is useful. But even though it looks like I have the correct structure returned, the data isn't showing in the Fiori preview. "No data found. Try adjusting the filter settings."

Service implementation:

    srv.on('READ', User, async req => {
        let result = {}
        if (req.query.cqn.count) {
            delete req.query.count
            delete req.query.cqn.count
            const queryObject = cqnToQuery(req.query, {
                kind: "odata"
              })
            const count = await ext.tx(req).get("/User/$count")
            result = await ext.tx(req).get(queryObject.path + "&$inlinecount=allpages")
            req.query.count = true
            req.query.cqn.count = true
            result.$count = count
        }
        else {
            result = await ext.tx(req).run(req.query)
        }

        result.map(entity => convertDatesv2Tov4(req, entity))
        return result;
    })

Apparently SuccessFactors doesn't support $inlinecount and therefore I'm getting an explicit $count in addition to the query. (This breaks combinations of $filter and $inlinecount I assume)

Data returned:

{
  "@odata.context": "$metadata#User",
  "@odata.count": "90",
  "value": [
    {
      "userId": "1",
      "defaultFullName": "AA BB"
    },
    {
      "userId": "23",
      "defaultFullName": "XX YY"
    }
  ]
}
OlenaT
Advisor
Advisor
0 Kudos

Hi Pieter,

As I mentioned in the link I gave you above, custom handlers in node.js runtime should use OData v4, not OData v2. Also the result variable should be an array (also written in the link), please adjust your result initialisation.

Are you using OData v2 adapter https://www.npmjs.com/package/@sap/cds-odata-v2-adapter-proxy or are you trying to make your own?

Best regards,

Olena

pieterjanssens
Active Participant

Hi Olena,

Thanks for the follow-up. The code that I shared was working, but I later found out that the issue had to do something with annotations or restricting the properties used in the Fiori preview. See the accepted answer.

Best regards,

Pieter

Accepted Solutions (1)

Accepted Solutions (1)

pieterjanssens
Active Participant
0 Kudos

See https://answers.sap.com/comments/13085009/view.html for the solution.

The issue "No data found. Try adjusting the filter settings." was resolved after using annotations to restrict the columns. I was not able to figure out why this is happening though.

merveguel
Participant
0 Kudos

Hi Pieter,

I am having a very similar issue, I am trying to make an OData call to the onpremise backend which does not support neither $inlinecount (OData v2) nor $count (OData v2) parameters. Therefore I am keep ending up with the issue even converting my model to OData V2. I am currently considering manually deleting the count parameters from the query in the service call as you did. I was wondering later were you able to find a better solution to it. Kindly see my thread regarding the issue I am having: https://answers.sap.com/questions/13909438/sap-cap-with-odata-v4-adds-count-param-to-uri-that.html

Best Regards,

Merve

Answers (1)

Answers (1)

jhodel18
Active Contributor
0 Kudos

Hi Pieter,

It seems that you've been hitting a lot of limitations in using the fluent api for your external service calls. I did encounter a handful of them and decided to breakaway from using the fluent api framework. What I did is call axios my self like below:

const axios = require("axios").default;
const client = axios.create(options); <--- options is my base request i.e. base URL and authentication
client.post(path, data) <--- for your case path = /User/$count

I believe your already know that cds framework uses axios behind the scenes. This is just merely a DIY procedure.