Hi all 👋
Is it possible to create a new record in a before change hook?
I've managed to seed my database using payload.create and etc, so I thought maybe that's how you create new records across the entire thing... but my approach below is definitely not correct. Can someone help put me back on the right path?
My goal:
When a user is created, they may or may not be assigned to a group.
If they are not assigned to a group upon creation, we will create a new group called "${user.name}'s Group"
and assign the user to that group before continuing to creating the user.
My Issue:
I can't find clear documentation on how to achieve something like this, so I've used my intuition and successfully gotten myself no closer than I was before. If y'all know of any documentation regarding this topic, I would greatly appreciate those references. I'm not sure if this is something traditionally done in Payload CMS, and if this isn't something I should be doing, please let me know.
import { CollectionConfig, CollectionBeforeChangeHook } from 'payload/types';
import payload from 'payload';
// create new user group
const newUserGroup = async (data): string => {
const { id: userGroupId } = await payload.create({
collection: 'user-groups',
data: {
name: data.name + '\'s Group',
}
});
return userGroupId;
}
const beforeChangeHook: CollectionBeforeChangeHook = async ({data, req, operation, originalDoc}) => {
// new users not assigned to a group will be assigned to a new group of their own
if(operation === 'create' && !data.userGroup) {
data.userGroup = await newUserGroup(data);
}
return data;
}
const Users: CollectionConfig = {
slug: 'users',
auth: true,
admin: { ... },
access: { ... },
fields: [
{
name: 'userGroup',
type: 'relationship',
relationTo: 'user-groups',
hasMany: false,
label: 'User Group',
},
...
],
hooks: {
beforeChange: [beforeChangeHook]
}
}thx!
Because I'm new to the JS ecosystem, I might be approaching this all wrong. I'm open to any suggestions!
This is absolutely something you can do. You have access to the
payloadinstance in the
reqargument passed to your hook. I would try using that instance instead of importing payload. Pass the instance as a second argument to newUserGroup
Thank you so much, dsod!
When I pass the req to the function and use its payload, I get an error that I'm not sure of how to resolve...
Here's my new function
const newUserGroup = async (data, req): string => {
const { id: userGroupId } = await req.payload.create({
collection: 'user-groups',
data: {
name: data.name + '\'s Group',
}
});
return userGroupId;
}Here's the error I get when it executes
[19:14:37] ERROR (payload): TypeError: Cannot read properties of undefined (reading 'config')
at create (/Users/kayla/sandbox/praise-n-raise/node_modules/payload/src/collections/operations/create.ts:39:25)
at createLocal (/Users/kayla/sandbox/praise-n-raise/node_modules/payload/src/collections/operations/local/create.ts:62:16)
at processTicksAndRejections (node:internal/process/task_queues:95:5)we need to work on some error messages, I believe this stems from using the wrong collection slug. Is your slug supposed to be ‘user-group’?
Woohoo!! That was the issue, thanks!
I'd also like to take note of an issue I ran into after resolving the wrong collection slug.
In my UserGroups collection, I have the following field
{
name: 'owner',
type: 'relationship',
relationTo: 'users',
defaultValue: ({ user }) => ( user.id ),
access: {
update: () => false,
},
}Because a
useris not the one creating this, I received the error below
ERROR (payload): TypeError: Cannot read properties of undefined (reading 'id')
at defaultValue (/Users/kayla/sandbox/praise-n-raise/src/collections/UserGroups.ts:24:32)I changed the defaultValue field in the UserGroups collection to the following
defaultValue: ({ user }) => ( user?.id ),and the program executed without any errors!
I am now able to create a new record in the beforeChange Hook 🙂
Thank you Jarrod and dsod for your help!
Nice! 👍 🎉 Any time
Star
Discord
online
Get dedicated engineering support directly from the Payload team.