dynamic data to the options field

default discord avatar
megetron
last month
9

can i load dynamic data to an options field?



the code below doesn't work but i would like to loop on a collection and gets its internal values like this:



fields: [
    {
        name: 'Facets',
      
        type: 'select',
        hasMany: true,

        options: [
         async () => {
            const facets =  await payload.find({
                collection: "facet",
            })

            let facet_values = facets.map(function (facet) {
                return facet.values;
            });

            let brands_and_categories = facet_values.map(function (v) {
                return {
                    value: v.name
                    key, v.id
                };
            });
            return brands_and_categories;
         }
     ],
]}
``


also note that i tried also to set relationship but then couldnt get the values of the 'facets' collection in the select box:

// {


// name: 'Facets',


// type: 'relationship',


// hasMany: true,


// relationTo: 'facets',


// },


```

  • discord user avatar
    jesschow
    Payload Team
    last month

    Hey @megetron - I would revert back to your relationship field and populate the values using a field hook like this:



    const getFacets: FieldHook = async () => {
      const facets = await payload.find({
        collection: 'facets',
      });
    
      if (facets.docs) {
        return facets.docs.map((doc) => doc.id);
      } return null;
    };


    {
      name: 'Facets',
      type: 'relationship',
      relationTo: 'facets',
      hasMany: true,
      hooks: {  
        afterRead: [getFacets], 
      },
     },
  • default discord avatar
    megetron
    last month

    thank you.


    i have reedited the function to retrieve the internal values of the facets collection:


    const getFacets: FieldHook = async () => {
      const facets = await payload.find({
        collection: 'facets',
      });
      
      
      if (facets.docs) {
        let values = facets.docs.map(obj => obj.values).flat();
        console.log(values)
        // return ['samsung', 'google'] // this wont work as well
        return values
    
      } 
      
      return null;
    };
    
    
    // console.log output
    // [
    //  { name: 'Google', code: 'google', id: '642d55dea5fdab6fb3d3fe02' },
    //  { name: 'Samsung', code: 'samsung', id: '642d55eca5fdab6fb373de08' },
    // ]


    where the output would be expected to be override the data in the select box.

  • discord user avatar
    jesschow
    Payload Team
    last month

    @megetron return only the id, this will pull in the full doc for you.

  • default discord avatar
    megetron
    last month

    it doesn't work as well, maybe because the id is not the id of the document, rather its the id of the internal 'values' key inside the facets document?



    maybe i will share the whole code, hopefully it will explain better than i did:



    // blocks/filter-by-facets.ts
    
    import { Block , FieldHook} from 'payload/types';
    import payload from 'payload';
    
    const getFacets: FieldHook = async () => {
      const facets = await payload.find({
        collection: 'facets',
      });
      
      
      if (facets.docs) {
        const ids = facets.docs.map(obj => obj.values.map(val => val.id)).flat();
        console.log(ids)
        //return '642d55dea5fdab6fb3d3fe02' // didnt work
        return ids
        
      } 
      
      return null;
    };
    
    
    export const FilterFacetsBlock: Block = {
      slug: 'FilterFacets',
      fields: [
        {
          name: 'Facets',      
          type: 'relationship',
          relationTo: 'facets',
          hasMany: true,
          hooks: {  
            afterRead: [getFacets], 
          },     
        },
        {
          name: 'ContainsAny',
          type: 'checkbox',
        },
        
      ]
    };



    // collections/collections.ts
    import { CollectionConfig } from 'payload/types';
    import { FilterFacetsBlock } from '../blocks/filter-by-facets';
    
    const Collections: CollectionConfig = {
      slug: 'collections',
    
      fields: [
        {
          name: 'productVariants',
          type: 'blocks',
          blocks: [
            FilterFacetsBlock, // here i would like the productVariants to be populated from the 'values' array inside the facet doc
          ]
        },
      ],
    }
    
    export default Collections;


    // facets collections 
    const facets: CollectionConfig = {
        slug: 'facets',
      
        fields: [
          {
            name: 'values',
            type: 'array',
            fields: [
              {
                name: 'name',
                type: 'text',
              },
              {
                name: 'code',
                type: 'text',
              },
                ]
          },
        ],
      }
      
      
  • discord user avatar
    jesschow
    Payload Team
    last month

    @megetron the code helps thanks! Is there a reason you're storing all the facets in one document? Instead of a document for each facet?



    And also yes it definitely needs to be the

    document.id

    for the relationship field

  • default discord avatar
    megetron
    last month

    ok thanks!




    that's a good question actually 🙂



    i am trying to design a store where you can create a filtered "Collection" to create "featured products", "best budget phones", etc..




    there are some optional filters (which each filter is representd by a block):


    1. filter by facets:


    - color: [blue, pink, black]


    - brand: [Apple, Logitech, Samsung]


    - category: [Electronics, Computers, Photo]


    - etc...



    2. select specific products in the collection


    3. filter by the product name (so you can filter by "startWith", "contains", etc..)


    4. and more of this filters




    so, i guess instead of creating one "facets" collection with document per each (color, brand, category) you could create a collection for each and relationship to the "products" collection.



    but then, i can filter the "products" collection without saving a filter mechanism for the "collections" ("featured products", "best budget phones" etc)



    thanks for your help, we can close it. i have decided to redesign.

  • default discord avatar
    seth
    last month

    I would take this a step further and say would be cool if an

    options

    callback had

    siblingData

    access, I have an array of selects such that I only want each option available once, such that if options are "A", "B", and "C" and they select "A" in the first array item, the next array item only has B and C available

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.