Guide
After Hook

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.