#dynamic data to the options field

11 messages · Page 1 of 1 (latest)

wispy vortex
#

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',
// },
ancient elm
#

Hey @wispy vortex - 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], 
  },
 },
wispy vortex
#

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.

ancient elm
#

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

wispy vortex
#

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',
          },
            ]
      },
    ],
  }
  
  
ancient elm
#

@wispy vortex 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

wispy vortex
#

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...
  1. select specific products in the collection
  2. filter by the product name (so you can filter by "startWith", "contains", etc..)
  3. 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)

wispy vortex
#

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

lavish sparrow
#

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

median jackal
#

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