Creating calculated attributes
Calculated attributes are attributes that might react to the creation/modification of other attributes. The values for these attributes are transformed prior to persistence in DynamoDB.
Example 1
In this example, we have an attribute "fee"
that needs to be updated any time an item’s "price"
attribute is updated. The attribute "fee"
uses watch
to have its setter callback called any time "price"
is updated via a put
, create
, update
, or patch
operation.
{
model: {
entity: "products",
service: "estimator",
version: "1"
},
attributes: {
product: {
type: "string"
},
price: {
type: "number",
required: true
},
fee: {
type: "number",
watch: ["price"],
set: (_, {price}) => {
return price * .2;
}
}
},
indexes: {
pricing: {
pk: {
field: "pk",
composite: ["product"]
},
sk: {
field: "sk",
composite: []
}
}
}
}
Example 2
In this example we have an attribute "descriptionSearch"
which will help our users easily filter for transactions by "description"
. To ensure our filters will not take into account a description’s character casing, descriptionSearch
duplicates the value of "description"
so it can be used in filters without impacting the original "description"
value. Without ElectroDB’s watch
functionality, to accomplish this you would either have to duplicate this logic or cause permanent modification to the property itself. Additionally, the "descriptionSearch"
attribute has used hidden:true
to ensure this value will not be presented to the user.
{
model: {
entity: "transaction",
service: "bank",
version: "1"
},
attributes: {
accountNumber: {
type: "string"
},
transactionId: {
type: "string"
},
amount: {
type: "number",
},
description: {
type: "string",
},
descriptionSearch: {
type: "string",
hidden: true,
watch: ["description"],
set: (_, {description}) => {
if (typeof description === "string") {
return description.toLowerCase();
}
}
}
},
indexes: {
transactions: {
pk: {
field: "pk",
composite: ["accountNumber"]
},
sk: {
field: "sk",
composite: ["transactionId"]
}
}
}
}