Skip to content

onDelete ​

Category
Tags
Export size
min 7.88 kB · gzip 3.19 kB
See also

Manipulates related items when a record is deleted, similar to SQL foreign key actions. Supports 'cascade' (remove related records) and 'set null' (nullify the foreign key). Unlike database-level cascades, this hook triggers service events and hooks for related items.

ts
  import { 
onDelete
} from 'feathers-utils/hooks';

Examples ​

Example 1 ​

ts
import { onDelete } from 'feathers-utils/hooks'

// remove the user's posts
app.service('users').hooks({
  after: {
    remove: [onDelete({ service: 'posts', keyHere: 'id', keyThere: 'userId', onDelete: 'cascade' })]
  }
})

Example 2 ​

ts
import { onDelete } from 'feathers-utils/hooks'

// set `posts.userId` to `null` and wait for it before returning
app.service('users').hooks({
  after: {
    remove: [
      onDelete({
        service: 'posts',
        keyHere: 'id',
        keyThere: 'userId',
        onDelete: 'set null',
        blocking: true,
      }),
    ]
  }
})

Options ​

serviceSrequired

The related service where related items should be manipulated

keyThereNeverFallback<keyof InferGetResult<H['app']['services'][S]>, string>required

The propertyKey in the related service

keyHerekeyof ResultSingleHookContext<H>required

The propertyKey in the current service.

onDeleteOnDeleteActionrequired

The action to perform on the related items.

  • cascade: remove related items
  • set null: set the related property to null
queryInferFindParams<H['app']['services'][S]>['query']

Additional query to merge into the service call. Typed based on the related service's query type.

multiMultidefaultservice.options.multi

Whether the related service allows manipulating multiple items in a single patch/remove call.

Defaults to the multi option of the related service. If multi is not allowed, the related items are fetched and manipulated with one patch/remove call per item.

blockingboolean | PredicateFn<H>defaultfalse

Whether the hook waits for the related-service call to finish before the call continues. Can be a boolean or a predicate that receives the HookContext.

Example

isProvider('external')

onError(error: any, context: H) => void

Called when a related-service call rejects while not blocking. Without this, fire-and-forget rejections are swallowed (but never leak as an unhandled rejection). In blocking mode the error is thrown to the caller instead.

Type declaration ​

Show Type Declarations
ts
export type OnDeleteAction = "cascade" | "set null"
export interface OnDeleteOptions<
  H extends HookContext = HookContext,
  S extends keyof H["app"]["services"] = keyof H["app"]["services"],
> {
  /**
   * The related service where related items should be manipulated
   */
  service: S
  /**
   * The propertyKey in the related service
   */
  keyThere: NeverFallback<keyof InferGetResult<H["app"]["services"][S]>, string>
  /**
   * The propertyKey in the current service.
   */
  keyHere: keyof ResultSingleHookContext<H>
  /**
   * The action to perform on the related items.
   *
   * - `cascade`: remove related items
   * - `set null`: set the related property to null
   */
  onDelete: OnDeleteAction
  /**
   * Additional query to merge into the service call.
   * Typed based on the related service's query type.
   */
  query?: InferFindParams<H["app"]["services"][S]>["query"]
  /**
   * Whether the related service allows manipulating multiple items in a single
   * `patch`/`remove` call.
   *
   * Defaults to the `multi` option of the related service. If multi is not
   * allowed, the related items are fetched and manipulated with one
   * `patch`/`remove` call per item.
   *
   * @default service.options.multi
   */
  multi?: Multi
  /**
   * Whether the hook waits for the related-service call to finish before the
   * call continues. Can be a boolean or a predicate that receives the
   * `HookContext`.
   *
   * @example isProvider('external')
   * @default false
   */
  blocking?: boolean | PredicateFn<H>
  /**
   * Called when a related-service call rejects while not blocking.
   * Without this, fire-and-forget rejections are swallowed (but never leak as an
   * unhandled rejection). In `blocking` mode the error is thrown to the caller instead.
   */
  onError?: (error: any, context: H) => void
}
type OnDeleteOptionsDistributed<H extends HookContext> = {
  [S in keyof H["app"]["services"] & string]: OnDeleteOptions<H, S>
}[keyof H["app"]["services"] & string]
/**
 * Manipulates related items when a record is deleted, similar to SQL foreign key actions.
 * Supports `'cascade'` (remove related records) and `'set null'` (nullify the foreign key).
 * Unlike database-level cascades, this hook triggers service events and hooks for related items.
 *
 * @example
 * ```ts
 *
 *
 * // remove the user's posts
 * app.service('users').hooks({
 *   after: {
 *     remove: [onDelete({ service: 'posts', keyHere: 'id', keyThere: 'userId', onDelete: 'cascade' })]
 *   }
 * })
 * ```
 *
 * @example
 * ```ts
 *
 *
 * // set `posts.userId` to `null` and wait for it before returning
 * app.service('users').hooks({
 *   after: {
 *     remove: [
 *       onDelete({
 *         service: 'posts',
 *         keyHere: 'id',
 *         keyThere: 'userId',
 *         onDelete: 'set null',
 *         blocking: true,
 *       }),
 *     ]
 *   }
 * })
 * ```
 *
 * @see https://utils.feathersjs.com/hooks/on-delete.html
 */
export declare const onDelete: <H extends HookContext = HookContext>(
  options: MaybeArray<OnDeleteOptionsDistributed<H>>,
) => (context: H, next?: NextFunction) => Promise<void>
ArgumentTypeDescription
optionsMaybeArray<OnDeleteOptionsDistributed<H>>
typemethodsmulti
after, aroundremoveyes

Released under the MIT License.