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.

dynamic data to the options field

default discord avatar
megetron_2 years ago
8

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',


// },


```

  • default discord avatar
    jessrynkar2 years ago

    Hey

    @1085675413130465291

    - 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_2 years ago

    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.

  • default discord avatar
    jessrynkar2 years ago
    @1085675413130465291

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

  • default discord avatar
    megetron_2 years ago

    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',
              },
                ]
          },
        ],
      }
      
      
  • default discord avatar
    jessrynkar2 years ago
    @1085675413130465291

    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_2 years ago

    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
    ssyberg2 years ago

    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

  • default discord avatar
    gaurav0034last year

    I am using payloadcms and in collection of posts I have


    {


    name: "category",


    type: "relationship",


    relationTo: "categories",


    required:true


    }, this category field , now I want to include subcategories field but it should show subcategories only from array which is present in selected category i also have subcategories collection and subcategories present in every category from that collection only



    My question is i have collection categories and collection subctegories, in categories collection i added subcategories throughe relationship, so while creating any post i need that my subcategories should populate in option depending upon selection of cetegory.But i am not able to do that so please help me with that

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.