Allow injectable entity subscribers
See original GitHub issueI’m submitting a…
[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Current behavior
Currently only the default subscription mechanism of typeorm is usable. While this is a good thing, it does not allow to inject other services into the subscriber instance.
Expected behavior
By defining a new service class decorator, like @EntitySubscriber
and the technique mentioned at https://github.com/typeorm/typeorm/issues/2630#issuecomment-447211212
we could implement a very easy way to implement rich subscribers which can participate in the nest injection container.
Minimal reproduction of the problem with instructions
I made a local solution myself which is straight forward, but works as expected:
// subscriber.decorator.ts
import { SetMetadata } from '@nestjs/common';
export const IS_SUBSCRIBER = 'IS_SUBSCRIBER';
export const Subscriber = () => SetMetadata(IS_SUBSCRIBER, true);
// app.module.ts (trimmed), guess this would be TypeORMModule.forRoot then
export class AppModule implements OnModuleInit {
constructor(
private readonly connection: Connection,
private readonly container: ModulesContainer,
private readonly reflector: Reflector,
) {}
onModuleInit() {
// find providers marked as entity subscribers...
const subscribers = [...this.container.values()]
.filter(({ providers }) => providers.size > 0)
.reduce(
(matching, { providers }) => [
...matching,
...[...providers.values()]
.filter(
provider =>
provider.instance &&
this.reflector.get(
IS_SUBSCRIBER,
provider.instance.constructor,
) === true,
)
.map(provider => provider.instance),
],
[],
);
// ...and hand those instances over to typeorm
subscribers.forEach(subscriber => {
this.connection.subscribers.push(subscriber);
});
}
}
I'm pretty sure this kind of feature should be easily transported into the typeorm nest package.
What is the motivation / use case for changing the behavior?
Its allows nestjs dependency injection inside of entity subscribers. For example:
// user-subscriber.service.ts
@Subscriber()
@Injectable()
export class UserSubscriberService implements EntitySubscriberInterface {
constructor(private readonly invitation: InvitationService) {}
listenTo() {
return User;
}
async beforeInsert(event: InsertEvent<User>) {
const email = event.entity.email;
const user = await event.manager.getRepository(User).findOne({
where: {
email,
},
});
if (user !== undefined) {
throw new BadRequestException(
`User with email '${email}' already exists`,
);
}
event.entity.status = UserStatus.UNREGISTERED;
event.entity.password = null;
}
async afterInsert(event: InsertEvent<User>) {
this.invitation.invite(event.entity);
}
}
This provider is added to the module as usual. It actually works almost the same as websocket services.
Environment
Nest version: 6.1.1
Nest/TypeORM version: 6.0.0
Others:
Issue Analytics
- State:
- Created 4 years ago
- Reactions:15
- Comments:13 (5 by maintainers)
Top Results From Across the Web
NestJS - Cannot inject a service into a subscriber
The only way I found to inject a dependency into a subscriber using NestJS, ... entities/revison.entity'; import { RevisionService } from '.
Read more >Subscribers a.k.a Entity Listeners of TypeORM on NestJS
There's no documented way to do it but with the power of the Dependency Injection, we can achieve to get it injected by...
Read more >Defining database subscribers | Vendure docs
By defining the subscriber as an injectable provider, and passing it to a Vendure plugin, you can take advantage of Nest's dependency injection...
Read more >Understanding Method Injection - Manning
Take the following ApplyDiscountFor method of a Product Entity for example, ... Allows injecting Dependencies into data-centric objects that ...
Read more >Database | NestJS - A progressive Node.js framework
To begin using the User entity, we need to let TypeORM know about it by inserting it into ... With that in place,...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Is there any chance to inject
REQUEST
object as well? I am struggling on implementing aBlameableColumn
, anyone has any thoughts?I ran into the same problem.