type StockStatus: String enum {
InStock = 'I';
OutOfStock = 'O';
};
entity Books: [...] {
[...]
stockStatus: StockStatus;
};
InStock
) and not the value set behind the enumeration value (aka. I
) as it could change over time. The code should consequently look like this:class CatalogService extends cds.ApplicationService {
init() {
this.on('submitOrder', async (req) => {
const { book, quantity } = req.data
const { stockStatus } = await SELECT `stockStatus` .from (Books,book)
if (stockStatus == StockStatus.InStock) {
[...]
} else {
[...]
}
});
[...]
return this.init();
}
}
StockStatus
module like this:module.exports = {
InStock: 'I',
OutOfStock: 'O'
};
const StatusCode = require('./StockStatus');
to the service implementation to achieve it but it still error-prone as developers need to carefully align values in the module with the values used in the enumeration definition.cds
facade with a new method called enums()
, returning the enumerations like the entities()
method. The bookshop service implementation would then look like this:const cds = require('@sap/cds')
const { Books } = cds.entities('sap.capire.bookshop')
const { StockStatus } = cds.enums('sap.capire.bookshop')
class CatalogService extends cds.ApplicationService {
init() {
this.on('submitOrder', async (req) => {
[...]
if (stockStatus == StockStatus.InStock) {
[...]
} else {
[...]
}
});
[...]
return this.init();
}
}
enums()
method in the cds
facade to return the enumerations. Since it is theoretically also possible to define enumerations in a service, we also need an enums()
method in the cds.Service
class.const cds = require('@sap/cds')
cds.on('loaded', (csn) => {
const enums = Object.keys(csn.definitions)
.filter((definitionName) => typeof csn.definitions[definitionName].enum === 'object')
.reduce((foundEnums, enumName) => {
const enumValues = {};
const enumDefinition = csn.definitions[enumName].enum;
for (let enumValueName of Object.keys(enumDefinition)) {
const enumValueDefinition = enumDefinition[enumValueName];
if (typeof enumValueDefinition === 'object' && Object.keys(enumValueDefinition).includes('val')) {
enumValues[enumValueName] = enumDefinition[enumValueName].val;
} else {
enumValues[enumValueName] = enumValueName;
}
}
foundEnums[enumName] = new Proxy(enumValues, {
get: (target, name, receiver) => {
if (Reflect.has(target, name)) {
return target[name];
} else {
throw new Error(`Enumeration '${enumName}' does not define value '${name}'`);
}
},
set: (target, name, receiver) => {
throw new Error(`Enumeration '${enumName}' cannot be modified`);
}
});
return foundEnums;
}, {});
const findEnumsByNamespace = (namespace) => {
if (!namespace) {
return enums;
} else {
return Object.keys(enums)
.filter((enumName) => enumName.length > namespace.length && enumName.substring(0, namespace.length) == namespace)
.reduce((filteredEnums, enumName) => {
const packageEndIndex = enumName.lastIndexOf('.', namespace.length);
const enumSimpleName = packageEndIndex < 0 ? enumName : enumName.substring(packageEndIndex + 1);
filteredEnums[enumSimpleName] = enums[enumName];
return filteredEnums;
}, {});
}
}
cds.extend(cds.__proto__).with({
enums: (namespace) => {
return findEnumsByNamespace(namespace || cds.db.namespace);
}
});
cds.extend(cds.Service).with(class {
enums(namespace) {
return findEnumsByNamespace(namespace || this.namespace);
}
});
});
server.js
or srv/server.js
file and the magic happens.stockStatus
attribute in the Book
entity, the StatusCode
enumeration is not referenced anywhere and cds.enums()
will not return it, although it is defined.You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
26 | |
25 | |
21 | |
12 | |
9 | |
9 | |
8 | |
8 | |
8 | |
7 |