Skip to content

Latest commit

 

History

History
101 lines (85 loc) · 2.37 KB

after-hook.mdx

File metadata and controls

101 lines (85 loc) · 2.37 KB
title
After Hook

import { Callout } from "nextra/components";

Executing Functions After Object Creation

If you want to execute a function after creating an object, use .after. The first argument is the created object, and the second argument is the variables.

import { factory } from "@factory-js/factory";
import { db } from "./db";

const userFactory = factory
  .define(
    {
      props: {
        name: () => "John",
      },
      vars: {
        greeting: () => "Hello",
      },
    },
    async (user) => {
      return db.user.create({ data: user });
    },
  )
  .after((user, vars) => {
    console.log(user, vars.greeting);
  });

await userFactory.create(); // 👉 Logs { name: "John" }, Hello to the console
`.after` is only executed when `.create` is called. It is not executed when creating objects with `.build`.

You can also add multiple hooks in a method chain.

await userFactory
  .after(() => console.log(1))
  .after(() => console.log(2))
  .after(() => console.log(3))
  .create(); // 👉 Logs 1 2 3 to the console

Creating One-to-Many Relationships

A useful case for .after is when you want to generate objects with one-to-many relationships, such as when using an ORM. In the example below, a user with three posts is created in a single .create call.

import { factory, later } from "@factory-js/factory";

// Define the user factory
const userFactory = factory.define(
  {
    props: {
      id: () => 1,
    },
    vars: {},
  },
  async (user) => {
    return db.user.create({ data: user });
  },
);

// Define the post factory
const postFactory = factory
  .define(
    {
      props: {
        userId: later<string>(),
        title: () => "title",
      },
      vars: {
        user: () => await userFactory.create(),
      },
    },
    async (profile) => {
      return db.profile.create({ data: profile });
    },
  )
  .props({
    userId: async ({ vars }) => (await vars.user).id,
  });

// Generate a user with three posts and save them to the database
await userFactory
  .after((user) => postFactory.vars({ user: () => user }).createList(3))
  .create();
In practice, rather than using `.after` on its own, it is more convenient to use it in combination with `.traits`. For more details, refer to [Trait](./trait).