title |
---|
After Hook |
import { Callout } from "nextra/components";
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
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
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();