Skip to content
Radosław Mejer edited this page May 18, 2020 · 1 revision

Knex offers limited support for events. Kex provides own layer for events. It is incompatible with Knex, although it's possible to use Knex events.

Kex splits events into two groups:

  1. pre-execution - they're emitted right before the execution of the query
  2. post-execution - they're emitted when after fetching the results from the query

Based on the query type Kex will emit following events:

  • fetching() / fetched(results)
  • updating(values, returning) / updated(results, values)
  • inserting(values, returning) / inserted(results, values)
  • deleting(returning) / deleted(results)

Kex will execute all of the listeners serially (one after another) and will wait for resolving of async listeners.

The listeners are bound with the query builder however, using its methods will be ineffective (at this point of execution the SQL query is already created).

Listeners for pre-execution events can alter the query in a limited way by:

  • canceling the execution of the query (in this case the query will return undefined)
  • modifying the received fields

Listeners for post-execution events can alter the results of the query.

Examples

Altering fetched results

User.on('fetched', event => {
  // depending of query the results field
  // can be either an array or an object
  event.results = Array.isArray(event.results)
    ? event.results.map(item => ({ ...item, hello: 'there!' }))
    : { ...event.results, hello: 'there!' }
})

Setting some values before insert

User.on('inserting', event => {
  // since knex supports both arrays and single objects in insert()
  // the event.values might be either an array or an object
  event.values = Array.isArray(event.values)
    ? event.values.map(item => ({ ...item, created_at: new Date() }))
    : { ...event.values, created_at: new Date() }
})

Cancelling the update

User.on('updating', async event => {
  const canUpdate = await checkSomething()
  
  if (!canUpdate) {
    event.cancel()
  }
})

One time events

Similar to Knex, it's possible to attach an event listener that will be executed only once.

Note that it's not attached to the model instance.

User.query()
  .on('fetched', event => {
    // do something
  })

Using knex events

User.query()
  .on('query-response', listener, { native: true })
Clone this wiki locally