LogoZonai

Update Hooks

beforeUpdate, afterUpdateSuccess, and afterUpdateError extension hooks.

Hook Signatures#

Future<void> beforeUpdate(T object, Jwt? jwt)
Future<void> afterUpdateSuccess(T before, T after, Jwt? jwt)
Future<void> afterUpdateError(Object error, Jwt? jwt)

beforeUpdate receives the row before the update is applied. afterUpdateSuccess receives two row parameters: the state before and the state after the update.

beforeUpdate#

Runs after rules pass, before the UPDATE executes. Can abort by throwing:

@override
Future<void> beforeUpdate(Event object, Jwt? jwt) async {
  if (object.endDate.isBefore(object.startDate)) {
    throw Exception('End date must be after start date');
  }
}

Note: object here is the current row, not the values being applied. The update hasn't happened yet.

afterUpdateSuccess#

Runs after the UPDATE commits. Receives both the old and new row states:

@override
Future<void> afterUpdateSuccess(User before, User after, Jwt? jwt) async {
  if (before.email != after.email) {
    // Email changed — require re-verification
    await mutate.update.one(
      table: 'users',
      updates: [Update.column('is_verified', UpdateValue.literal(false))],
      where: Eq('id', after.id.value),
    );
    await email.send.verifyEmail(after);
  }
}

Use for: detecting field changes, notifying subscribers, resetting verification state.

afterUpdateError#

Runs if the UPDATE fails. Cannot make the operation succeed.

@override
Future<void> afterUpdateError(Object error, Jwt? jwt) async {
  logger.error('Update failed: $error');
}

Detecting Field Changes#

Compare before.<field> and after.<field> in afterUpdateSuccess:

if (before.status != after.status && after.status == 'published') {
  // Post was just published — send notifications
}