cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Entity keys in an event handler in CAP using TypeScript

jasonmuzzy
Active Participant
0 Likes
280

I'm converting a CAP project to TypeScript and the generated entity types work really well with CRUD event handlers, but for actions/functions the req.params object is generically typed, requiring extra effort to extract the entity keys.  It's odd since the req.data object is typed to include action parameters, so I would expect the key fields to be typed as well.

Below is my example code.  You can see I'm using a type predicate to inform TypeScript of the shape of req.params so it accepts req.params[0].KEYFIELD1, etc.

Is there a better way to do this?  I need the key fields since this is a mashup service that needs to include them in a call to an on-prem service.  req.subject has the key fields and values but I couldn't find a way to use it in an INSERT.  I was expecting that req.params would be a generic of type entity[].

 

import cds from '@sap/cds'
import { LocalEntity } from '#cds-models/LocalService'
import { OnPremHeaderSet } from '#cds-models/ZONPREM_SERVICE';

export class LocalService extends cds.ApplicationService {
    async init() {

        const OnPremService = await cds.connect.to('ZONPREM_SERVICE');

        this.on(LocalEntity.actions.approve, req => {

            // Have to use a type predicate since req.params (cds-types.Request_2.params) is generically typed as (string | object)[]
            // Could we use req.subject instead (which contains keys and values)?
            interface Key {
                KEYFIELD1: string,
                KEYFIELD2: string
            }

            const isKey = (param: string | object): param is Key => {
                return typeof param === 'object' && param !== null && 'KEYFIELD1' in param && 'KEYFIELD2' in param;
            }

            if (isKey(req.params[0])) {
                return OnPremService.run(INSERT.into(OnPremHeaderSet).entries({
                    KeyField1: req.params[0].KEYFIELD1,
                    KeyField2: req.params[0].KEYFIELD2,
                    Attribute: req.data.Attribute ?? ''
                }));
            } else {
                req.reject(400, 'Invalid request');
            }
        });

        return super.init()
    }
}

 

Accepted Solutions (0)

Answers (0)