Listening to occasions in TypeORM entities
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
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 —
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
QueryBuilderand repository/supervisor strategies.
To create a
Subscriber, you could:
- Mark the category with the
- Have your class implement the
EntitySubscriberInterface<T>which takes your
Entityclass as its sort parameter.
- Add the
listenTo()methodology that ought to merely return your entity class to specify that this subscriber might be listening solely to occasions of your entity.
- Implement the occasion strategies that you simply want.
- Specify your subscriber in
DataSourceOptionssince TypeORM v 0.3.0) choices like this:
subscribers: [ MyEntitySubscriber ].
- 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
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
supervisor properties of the
occasion object. The
entity may have our entity object with our information, and
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
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!