Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Create New Record in beforeChange Hook ?

default discord avatar
browniedev3 years ago
5

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!

  • default discord avatar
    dsod3 years ago

    This is absolutely something you can do. You have access to the

    payload

    instance in the

    req

    argument passed to your hook. I would try using that instance instead of importing payload. Pass the instance as a second argument to newUserGroup

  • default discord avatar
    browniedev3 years ago

    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)
  • discord user avatar
    jarrod_not_jared
    3 years ago
    @1047669407708610661

    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’?

  • default discord avatar
    browniedev3 years ago

    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

    user

    is 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!

  • default discord avatar
    dsod3 years ago

    Nice! 👍 🎉 Any time

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.