Make previous value available in @AfterUpdate function
Problem
By popular request, it would be very useful if we could also access the previous state of objects being updated in @AfterUpdate functions For example: [code block] Could become [code block] TypeORM already knows the previous value, as it will only call `@AfterUpdate` if it detects a change, therefore, the feature would only require that to be exposed to developer. Please see comment and thread - https://github.com/typeorm/typeorm/issues/1609#issuecomment-484303500 Thank you!
Unverified for your environment
Select your OS to check compatibility.
2 Fixes
Expose Previous Values in @AfterUpdate Hook in TypeORM
TypeORM's @AfterUpdate lifecycle event does not currently provide access to the previous state of an entity being updated. This limitation arises because the event is triggered only after a change is detected, but the previous values are not made available to the developer, hindering the ability to perform operations that depend on the previous state.
Awaiting Verification
Be the first to verify this fix
- 1
Modify TypeORM's EntitySubscriberInterface
Extend the EntitySubscriberInterface to include a new method that captures the previous state of the entity before the update occurs. This will involve adding a mechanism to store the previous values when the entity is loaded.
typescriptimport { EntitySubscriberInterface, EventSubscriber, UpdateEvent } from 'typeorm'; @EventSubscriber() export class MyEntitySubscriber implements EntitySubscriberInterface<MyEntity> { beforeUpdate(event: UpdateEvent<MyEntity>) { // Store previous values in a temporary variable event.entity.previousValues = { ...event.databaseEntity }; } afterUpdate(event: UpdateEvent<MyEntity>) { console.log('Previous Values:', event.entity.previousValues); } } - 2
Implement Previous Value Storage
Ensure that the previous values are stored in the entity itself or a dedicated property that can be accessed in the @AfterUpdate method. This may involve modifying the entity class to include a property for previous values.
typescriptexport class MyEntity { // Other properties... previousValues?: Partial<MyEntity>; } - 3
Update TypeORM Configuration
Ensure that the subscriber is registered in the TypeORM connection options so that it can listen to the update events and execute the new logic.
typescriptimport { createConnection } from 'typeorm'; import { MyEntitySubscriber } from './MyEntitySubscriber'; createConnection({ // Other connection options... subscribers: [MyEntitySubscriber], }); - 4
Test the Implementation
Create unit tests to verify that the previous values are correctly captured and logged during the @AfterUpdate event. Ensure that the tests cover various scenarios of entity updates.
typescriptimport { getConnection } from 'typeorm'; async function testAfterUpdate() { const entity = await getConnection().getRepository(MyEntity).findOne(1); entity.someProperty = 'newValue'; await getConnection().getRepository(MyEntity).save(entity); // Check logs or assertions for previous values }
Validation
Run the application and perform an update on an entity. Check the console logs to confirm that the previous values are displayed correctly in the @AfterUpdate method. Additionally, run the unit tests to ensure all scenarios pass successfully.
Sign in to verify this fix
1 low-confidence fix
Expose Previous Values in @AfterUpdate Function
The @AfterUpdate function in TypeORM does not currently provide access to the previous state of the entity being updated. This limitation arises because the event handler is only triggered after the update has been processed, without retaining the original values for comparison or logging purposes.
Awaiting Verification
Be the first to verify this fix
- 1
Modify TypeORM Entity to Include Previous State
Extend the functionality of TypeORM's entity lifecycle events by creating a wrapper that captures the previous state of the entity before it is updated.
typescriptclass MyEntity { @PrimaryGeneratedColumn() id: number; @Column() name: string; @BeforeUpdate() capturePreviousState() { this.previousState = { ...this }; } @AfterUpdate() logChanges() { console.log('Previous State:', this.previousState); console.log('Current State:', this); } } - 2
Implement a Before Update Hook
Use the @BeforeUpdate decorator to store the current state of the entity in a temporary variable before the update occurs. This allows access to the previous state in the @AfterUpdate function.
typescriptlet previousState: any; @BeforeUpdate() function capturePreviousState() { previousState = { ...this }; } - 3
Access Previous State in After Update Hook
In the @AfterUpdate function, access the stored previous state variable to compare or log changes after the update has been applied.
typescript@AfterUpdate() function logChanges() { console.log('Previous State:', previousState); console.log('Updated State:', this); } - 4
Test the Implementation
Create unit tests to ensure that the previous state is correctly captured and logged during the update process. Verify that the output matches expected values.
typescriptit('should log previous state on update', async () => { const entity = await repository.findOne(id); entity.name = 'New Name'; await repository.save(entity); // Check logs or mock console output });
Validation
Confirm that the @AfterUpdate function logs both the previous and current state of the entity after an update operation. Unit tests should pass without errors, demonstrating that the previous state is accurately captured and accessible.
Sign in to verify this fix
Environment
Submitted by
Alex Chen
2450 rep