Getting fields' config in beforeChange collection hook

default discord avatar
Tinouti
8 months ago
20

The

data

argument of the

beforeChange

collection hook looks like this:


{
  slug: 'slug-in-german',
  title: 'Title in German',
  excerpt: 'The excerpt goes here.',
  _status: 'draft',
}

I'd like to get the config of each of these fields

(ultimately to know whether or not the field is

localized: true

or not).



I went in and used

req.payload.config.collections

, filtered it to get the current collection, and started parsing that to try and reduce it to something that would look like this:



{
  slug: false,
  title: true, 
  excerpt: true,
  _status: false,
}


But once you start adding Tabs and Groups and Arrays and Blocks and ... into the mix, it start getting a little hairy and feeling grosser and grosser. 😅



There's got to be a better way, right? 👀 🤔

  • default discord avatar
    Alessio 🍣
    8 months ago

    Or I wonder if the

    buildStateFromSchema

    function might do it for you!



    Try passing in the fields array into buildStateFromSchema and see what happens

  • default discord avatar
    Tinouti
    8 months ago

    Oooh you got me excited, let me give that a go! 👀



    Hmmm doesn't seem to be quite what I need, this is what

    buildStateFromSchema

    returns:



    {
      title: {
        valid: true,
        value: 'Title in German',
        initialValue: 'Title in German',
        validate: [Function (anonymous)],
        condition: undefined,
        passesCondition: true
      },
      slug: {
        valid: true,
        value: 'slug-in-german',
        initialValue: 'slug-in-german',
        validate: [Function (anonymous)],
        condition: undefined,
        passesCondition: true
      },
      ...
    }
  • default discord avatar
    Alessio 🍣
    8 months ago

    hm



    what about

    reduceFieldsToValues

    ?



    or wait



    the main problem is parsing more complex blocks isn't it?



    e.g. blocks with subfields?

  • default discord avatar
    itsjxck
    8 months ago

    You could always just import your collection config directly



    But again, you would probably need to still handle nested fields

  • default discord avatar
    Alessio 🍣
    8 months ago

    wouldn't that result in the same data compared to using req.payload.config.collections?

  • default discord avatar
    itsjxck
    8 months ago

    Likely, but you could skip the faff of filtering from the collections array if you want to get the config of a specific static collection

  • default discord avatar
    Tinouti
    8 months ago

    Yeah getting the full config is pretty straightforward here one way or the other, the tricky part is mapping the data to their associated field config... 🤔

  • default discord avatar
    itsjxck
    8 months ago

    You might have to make a recursive parser to get the output you specifically want

  • default discord avatar
    Tinouti
    8 months ago

    Another to approach the problem I have could be to find a way to emulate the

    afterChange

    state of the doc with

    locale: "all"

    .



    For example, following my initial example, if I could get:


    {
      id: '642609c1a7d2bc624df538da',
      title: { 
        en: 'Title in English', 
        de: 'Title in German' 
      },
      slug: { 
        en: 'slug-in-english', 
        de: 'slug-in-german' 
      },
      excerpt: { 
        de: 'The excerpt goes here.' 
      },
      _status: 'draft',
      createdAt: '2023-03-30T22:14:25.318Z',
      updatedAt: '2023-04-05T07:02:50.800Z'
    }

    ie:

    findByID

    result + the current operation's data, I'd be golden. 🙌



    I may have to do more digging into how Payload work on the inside. 😅



    Yeah that's what I started doing and it quickly started feeling a bit "gross". And given that Payload probably already do this somehow somewhere, I figured that I probably shouldn't be reinventing the wheel and that maybe someone would know where the magic happens within Payload - and how to utilize it. 😊



    Haven't had the chance to dig more into this yet today, but giving it a bump in case anyone who knows how Payload works on the inside happens to be around and has thoughts. 🙏

  • default discord avatar
    Jarrod
    7 months ago

    I think the recursive parser is a fine approach, you would just separate your parsing functions into field types and loop over the a collection config and generate this obj/map



    What are you trying to achieve, would a fieldHook work better for you?

    https://payloadcms.com/docs/hooks/fields
  • default discord avatar
    Tinouti
    7 months ago

    Ah thanks Jarrod! The fieldHook approach could work indeed, although I'd then need to loop over every field in my plugin where I extend the config and add a hook to them. And I'll probably have to go through the same kind of recursive parser to achieve that. 🤔



    That being said, both @thompsonsj (

    https://github.com/payloadcms/payload/discussions/1508

    ) and @Exo (

    https://discord.com/channels/967097582721572934/967097582721572937/1093593337954574386

    ) might have already solved this in their own plugins, so I'm gonna check their work and learn from it before trying to reinvent the wheel. 😄



    I'll try to remember to close the loop on this thread once I have. 👍

Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.