Homelab, Linux, JS & ABAP (~˘▾˘)~
 

[CAP] Invoke custom handlers when querying local entity

const cds = require('@sap/cds');

module.exports = async srv => {

     const { Objects } = srv.entities // entities from myService.cds
   
     srv.on("myAction", async req => {
        const query = SELECT.one.from(Objects).where({ id: req.data.myId })
        const srv = await cds.connect.to('myService')
        const data = await srv.run(query)
        console.log(data) 
        return data
    })

    srv.on("READ", Objects, async req => {
        console.log("Objects called")
        // Select data from db or forward query to external system
        // ...
        // return data
    })

}

[CAP] BAS – port 4004 is already in use by another server process

If the default port 4004 is already open and you want to see what is bound to it, select View -> Find Command -> Ports Preview

Solution to kill another “watch.js” process using/blocking the port: https://answers.sap.com/questions/13016130/sap-business-application-studio-stop-running-serve.html
To archive the same in a single command use:

lwctl -c basic-tools kill -9 $(lwctl -c basic-tools ps aux | grep watch.js | awk '{print $2}')

As alternative, change the default port by adding a new port in package.json to the start script, for example: “start”: “cds run –port 4003” and use npm run start instead of cds watch.


Update 20.02.2023: Just had the problem again due to a VPN disconnect. But this time I had an application running using cds run. Therefore, I had to change the command from watch.js to cds.js:

lwctl -c basic-tools kill -9 $(lwctl -c basic-tools ps aux | grep cds.js | awk '{print $2}')

Update 10.05.2023: A better approach seems to be killing the node process. This should work in both situation.

lwctl -c basic-tools kill -9 $(lwctl -c basic-tools ps aux | grep node | awk '{print $2}')

Update 29.02.2024: With the BAS migration to Code – OSS the previous commands were not working anymore, but this new command seems to work:

kill -9 $(ps aux | grep cds.js | awk '{print $2}')

[CAP] Query teamMembersSize from SuccessFactors

const sfsfSrv = await cds.connect.to('sfsf')

// Option 1: Query Notation
const response = await sfsfSrv.run(SELECT`teamMembersSize`.from`User`.where`userId = ${req.user.id}`)
console.log("option 1: " + response[0].teamMembersSize)

// Option 2: HTTP method-style
const response2 =  await sfsfSrv.get(`/User('${req.user.id}')/teamMembersSize/$value`)
console.log("option 2: " + response2)

[CAP] Easy way to test if your approuter is working

An easy way to test your approuter is using the user-api-service. For that add the following route to your xs-app.json

    {
        "source": "^/user-api(.*)",
        "target": "$1",
        "service": "sap-approuter-userapi"
    }

And after deployment, open the application router URL and add /user-api/currentUser to it. You should see your Email and other User details. This is testing that the application router is actually getting the security token from the UAA instance.

[CAP] Set credentials in package.json via .env

https://developers.sap.com/tutorials/btp-app-ext-service-add-consumption.html#ebedc445-68de-4cd2-befd-6e31897852a8

These three entries in a .env file

cds.requires.ECEmploymentInformation.[development].credentials.authentication=BasicAuthentication
cds.requires.ECEmploymentInformation.[development].credentials.username=myUsername
cds.requires.ECEmploymentInformation.[development].credentials.password=myPassword

are equal to line 12, 13, and 14 in this package.json snippet:

{
    "cds": {
      "ECEmploymentInformation": {
        "kind": "odata-v2",
        "model": "srv/external/ECEmploymentInformation",
        "credentials": {
          "[production]": {
            "destination": "sfsf"
          },
          "[development]": {
            "url": "https://apisalesdemo2.successfactors.eu/odata/v2",
            "authentication": "BasicAuthentication",
            "username": "myUsername",
            "password": "myPassword",
          }
        }
      }
    }
}