TypeORM Entity Listeners — Exploring Best Practices and Caveats | by Dmitry Shamshurin | Apr, 2022 | Better Programming

Listening to occasions in TypeORM entities

Picture by Gabriel Heinzer on Unsplash

One of many base ideas in TypeORM (in addition to in lots of different ORMs) is the Entity. An Entity represents your information mannequin, it’s “a category that maps to a database desk (or assortment when utilizing MongoDB)”.

Principally, all the things revolves round it, we work together with entities in many alternative methods: we create, replace, edit, delete them. And very often, after (or earlier than) we carry out considered one of these operations, we have to carry out another motion, add some customized logic.

It could possibly be one thing so simple as logging or organising some default worth, but in addition one thing like updating different entities in a sure approach. We will write this manually in our lessons (repositories, providers, and so forth.) which is usually a bit tedious. To assist us with this job TypeORM presents us a really useful gizmo — Entity Listeners (or we will name them hooks).

As TypeORM documentation states, “Entity Listeners are strategies with customized logic that hearken to particular entity occasions.” The simplest and most easy option to implement these listeners is so as to add a particular decorator to that methodology outlined on the Entity. Right here is an instance:

With this decorator, each time earlier than we create a brand new Creator, we’ll generate an e-mail area on it in case it isn’t supplied

However what if you could add one thing extra advanced than this? E.g. add another database name. Once we simply began utilizing these hooks (with out earlier expertise with TypeORM), we merely added this logic within the hook like this (don’t thoughts the entity and property names, they aren’t actually related for this text):

Apparently, it is a fallacious strategy.

We observed that solely after we tried to make use of this entity in transactions and stored getting errors (TypeORM documentation tells us that we shouldn’t make any database calls within the listeners, however who reads the docs, proper?).

I just lately wrote an article on working with transactions in TypeORM, and one of the vital necessary issues to notice there was— you could use Transactional Supervisor whenever you do one thing within a transaction.

As you possibly can see within the instance above, these listeners don’t know something about our transaction and its transactional supervisor, so all the Insert and Replace operations had been failing. This was the purpose the place we realized that we’re doing one thing fallacious, and found one other, correct approach of working with Entity Listeners when the database is concerned — Subscribers.

A Subscriber is a category marked with @EventSubscriber() decorator as an occasion subscriber which may hearken to particular entity occasions or any entity occasions. Occasions are firing utilizing QueryBuilder and repository/supervisor strategies.

To create a Subscriber, you could:

  1. Mark the category with the @EventSubscriber decorator.
  2. Have your class implement the EntitySubscriberInterface<T> which takes your Entity class as its sort parameter.
  3. Add thelistenTo() methodology that ought to merely return your entity class to specify that this subscriber might be listening solely to occasions of your entity.
  4. Implement the occasion strategies that you simply want.
  5. Specify your subscriber in ConnectionOptions (or DataSourceOptions since TypeORM v 0.3.0) choices like this: subscribers: [ MyEntitySubscriber ].
  6. If you could implement a subscriber that can hearken to occasions of all entities, don’t add the listenTo() methodology and don’t specify the sort parameter within the EntitySubscriberInterface.

You’ll be able to examine subscribers and occasions (together with a full checklist of them) here. So, let’s repair our code and take a look at this instance:

As you possibly can see, many of the code within the occasion strategies remained the identical with one essential distinction — we’re utilizing the entity and supervisor properties of the occasion object. The entity may have our entity object with our information, and supervisor (or queryRunner should you want it) gives us a option to work together with the database.

It is rather necessary that every one database operations within the occasion listeners are carried out utilizing the occasion object’s queryRunner or supervisor occasion. This eliminates the aforementioned transaction drawback as a result of right here we obtain an occasion of our transactional supervisor, and we’re not breaking the scope of our transaction.

I hope this text was useful and supplied you with a greater understanding of how you can work with TypeORM entity hooks (listeners). As at all times, I recognize your suggestions. Blissful coding!

Extra to learn

  1. TypeORM documentation on Entities
  2. TypeORM documentation on Entity Listeners and Subscribers
  3. How to work with transactions in TypeORM

More Posts