entity-routes logo
Docs

Decorator functions#

What problem does it solve ?#

When you need to dynamically add attributes to your entity properties recursively (which means computed properties can't meet your needs), maybe depending on the metadata, a concrete example of that case are subresources IRIs.

How#

Decorator functions recursively traverse an item to decorate it.

They get access to DecorateFnArgs, among them there is the current item metadata & a clone/ref to update in any way an item's property (or even completely re-assign the item to another type).

A decorator function can be async and therefore will be awaited before passing the updated item to the next decorator function.

Usage#

With these entities :

#
ts
1// Shortened entity with only relevant parts
2class User extends AbstractEntity {
3 name: string;
4 email: string;
5 role: Role;
6 articles: Article[];
7}
9const user = new User();
10user.name = "Alex";
11user.email = "email@test.com";
13const role = new Role();
14// [...]
15user.role = role;
17const article1 = new Article();
18// [...]
19const article2 = new Article();
20// [...]
21user.articles = [article1, article2];

A very simple decorator function :

#
ts
1const data = { abc: 123, test: "just testing" };
3const decorateFn: DecorateFn<User, typeof data> = (args) => {
4 args.clone.testProp = "added_prop";
5 for (const key in args.data) {
6 args.clone[key] = args.data[key as keyof typeof data];
7 }
8};
9const decorated = await decorator.decorateItem({
10 rootItem: user,
11 rootMetadata: getRepository(User).metadata,
12 data,
13 decorateFn,
14});

The result could look like this :

#
json
1{
2 "id": 1,
3 "name": "Alex",
4 "email": "email@test.com",
5 "role": {
6 "id": 1,
7 "title": "Admin",
8 "startDate": "2020-10-21T09:15:39.100Z",
9 "testProp": "added_prop"
10 },
11 "articles": [
12 { "id": 1, "testProp": "added_prop" },
13 { "id": 2, "testProp": "added_prop" }
14 ],
15 "testProp": "added_prop"
Prev
Examples
Next
Introduction