Upload Field in Block only Populates ID

default discord avatar
ethelien
last month
32

Hello I have the following block config:


...
 {
  name: 'image',
  label: 'Academy Images',
  type: 'upload',
  relationTo: 'lms-media',
  maxDepth: 20,
  admin: {
    condition: (_, siblingData) => siblingData?.folder === 'lms-media',
  },
  access: {
    read: (): boolean => true,
  }
},
...

and I am expecting with the

depth=20

parameter for this field to be populated, but no matter what I do only the ID is returned. This is the link to an example collection:



https://planted-cms.herokuapp.com/api/helpArticles/64b125dfd18359bff265e3ac?locale=de&depth=20

this part:


{
  "folder": "lms-media",
  "image": "6475ddd3731d01a5f5eaab1d",
  "alignment": "left",
  "maxWidth": 100,
  "id": "64c3c008f9c25cc27cc14c7b",
  "blockType": "cloudinary-image"
}

should return the data for the image itself

  • default discord avatar
    notchr
    last month

    @ethelien Does this happen if you set the

    depth

    property to a high number?



    (Out of curiosity)

  • default discord avatar
    ethelien
    last month

    yes I tried 100+



    the collection has read => true so it should not have access issues

  • default discord avatar
    notchr
    last month

    @ethelien Okay, happy to help debug - what version of Payload are you using?



    (You can check in package.json)

  • default discord avatar
    ethelien
    last month

    latest 1.11.8

  • default discord avatar
    notchr
    last month

    Access control on lms-media is open as well?

  • default discord avatar
    paulpopus
    last month

    the media collection itself? can you access it via the API directly?



    just making sure

  • default discord avatar
    notchr
    last month

    ^

  • default discord avatar
    ethelien
    last month
  • default discord avatar
    paulpopus
    last month

    max depth defaults to 10 in the global config, to prevent abuse as it hits your server harder

    https://payloadcms.com/docs/production/preventing-abuse#max-depth


    unfortunately it doesnt fix the issue at hand

  • default discord avatar
    ethelien
    last month

    right, even if I set a higher number for the maxDepth in the payload config it still only returns the id



    the only thing I could right now as a workaround is to request the images seperately with their id but that seems nasty in regards to waitign times and state setting etc.

  • default discord avatar
    paulpopus
    last month

    yeah this is weird, i dont use the REST API often tbh



    @ethelien can we see your collection config?



    the full thing

  • default discord avatar
    ethelien
    last month

    which one?

  • default discord avatar
    paulpopus
    last month
    helpArticles
  • default discord avatar
    ethelien
    last month
    import { CollectionConfig } from 'payload/types';
    import { Content } from '../../blocks/Content';
    import slugField from '../../fields/slug';
    import { access } from './access';
    
    const HelpArticles: CollectionConfig = {
      slug: 'helpArticles',
      admin: {
        group: 'Help Articles',
        useAsTitle: 'title',
      },
      access: access,
      fields: [
        {
          name: 'title',
          label: 'Title',
          type: 'text',
          required: true,
        },
        {
          name: 'description',
          label: 'Description',
          type: 'textarea',
        },
        {
          name: 'content',
          label: 'Content',
          type: 'blocks',
          blocks: [
            Content,
          ],
          required: true,
        },
        slugField,
      ],
    };
    
    export default HelpArticles;


    this is access:


    import { isAdmin, isEditor, isAcedemy, isMarketing } from "../../../helpers/checkRole";
    
    export const access = {
      read: (): boolean => true,
      create: ({ req: { user } }): boolean => isAdmin(user) || isEditor(user) || isAcedemy(user) || isMarketing(user),
      update: ({ req: { user } }): boolean => isAdmin(user) || isEditor(user) || isAcedemy(user) || isMarketing(user),
      delete: ({ req: { user } }): boolean => isAdmin(user) || isEditor(user) || isAcedemy(user) || isMarketing(user),
    };


    this is content:


    import type { Block, Field } from 'payload/types'
    
    import { backgroundColor } from '../../fields/backgroundColor'
    import link from '../../fields/link'
    
    // Blocks
    import { RichText } from '../richText'
    import CloudinaryImageBlock from '../cloudinaryImage'
    import LoomEmbedBlock from '../loomEmbed'
    
    const columnFields: Field[] = [
      {
        name: 'size',
        type: 'select',
        defaultValue: 'oneThird',
        options: [
          {
            value: 'oneThird',
            label: 'One Third',
          },
          {
            value: 'half',
            label: 'Half',
          },
          {
            value: 'twoThirds',
            label: 'Two Thirds',
          },
          {
            value: 'full',
            label: 'Full',
          },
        ],
      },
      {
        name: 'content',
        type: 'blocks',
        blocks: [
          RichText,
          CloudinaryImageBlock,
          LoomEmbedBlock,
        ]
      },
      {
        name: 'enableLink',
        type: 'checkbox',
      },
      link({
        overrides: {
          admin: {
            condition: (_, { enableLink }) => Boolean(enableLink),
          },
        },
      }),
    ]
    
    export const Content: Block = {
      slug: 'content',
      fields: [
        backgroundColor({}),
        {
          name: 'columns',
          type: 'array',
          fields: columnFields,
        },
      ],
    }


    and this is the cloudinaryImage block:


    import { Block } from 'payload/types';
    
    const CloudinaryImageBlock: Block = {
      slug: 'cloudinary-image',
      labels: {
        singular: 'Cloudinary Image',
        plural: 'Cloudinary Images',
      },
      fields: [
        {
          name: 'folder',
          type: 'select',
          defaultValue: 'lms-media',
          options: [
            { label: 'Acadamy', value: 'lms-media' },
            { label: 'Marketing', value: 'marketingMedia' },
            { label: 'Help FAQ', value: 'supportMedia' },
          ],
          required: true,
        },
        {
          name: 'image',
          label: 'Academy Images',
          type: 'upload',
          relationTo: 'lms-media',
          maxDepth: 20,
          admin: {
            condition: (_, siblingData) => siblingData?.folder === 'lms-media',
          },
          access: {
            read: (): boolean => true,
          }
        },
        {
          name: 'image',
          label: 'Marketing Images',
          maxDepth: 20,
          type: 'upload',
          relationTo: 'marketingMedia',
          admin: {
            condition: (_, siblingData) => siblingData?.folder === 'marketingMedia',
          },
          access: {
            read: (): boolean => true,
          }
        },
        {
          name: 'image',
          label: 'Help FAQ Images',
          maxDepth: 20,
          type: 'upload',
          relationTo: 'supportMedia',
          admin: {
            condition: (_, siblingData) => siblingData.folder === 'supportMedia',
          },
        },
        ...
    
      ],
    };
    
    export default CloudinaryImageBlock;
  • default discord avatar
    paulpopus
    last month

    can we test removing

    read: (): boolean => true,

    on the cloudinary block? im beginning to wonder if its a bug



    another thing, i recommend against duplicate field names

    name: 'image',


    i see that you're conditionally showing them but the

    name

    is a machine name, relating to tables/table columns in the database so each field should have a unique value



    i think its ok for now cause mongodb is that flexible but you might have issues come 2.0 version

  • default discord avatar
    ethelien
    last month

    it was actually something recommended here because I have multipe media collections depending on the area



    but I only wanted to have 1 Image block where I could reference the media needed

  • default discord avatar
    paulpopus
    last month

    ok im not gonna go against that recommendation then but lets try the removing the access function

  • default discord avatar
    ethelien
    last month

    I have removed that condition but still same same

  • default discord avatar
    paulpopus
    last month

    if that doesnt work, then I wanna try adding a relationship field directly to your helpArticles collection



    and to see if we can at least populate

    that
  • default discord avatar
    ethelien
    last month

    ok

  • default discord avatar
    paulpopus
    last month

    then we know that collection/config is fine

  • default discord avatar
    ethelien
    last month

    so...



    if I create a relationship field and select the respective image from that relation it gets populated

  • default discord avatar
    paulpopus
    last month

    not sure, would you be able to put this in a reproducible repo? (or share your own repo?)



    im thinking it could be a bug, I saw @jarrod_not_jared was in another thread about a similar depth issue and having it reproducible would help a lot in figuring that part out

  • discord user avatar
    jmikrut
    Payload Team
    last month

    @ethelien what is your access control for the

    lms-media

    collection?



     {
      name: 'image',
      label: 'Academy Images',
      type: 'upload',
      relationTo: 'lms-media',
      maxDepth: 20,
      admin: {
        condition: (_, siblingData) => siblingData?.folder === 'lms-media',
      },
      access: {
        read: (): boolean => true,
      }
    },


    I see here that you have read access set to true on the

    image field itself

    , but you also need read access to the

    lms-media

    collection



    i dont think this has anything to do with depth at all

  • default discord avatar
    paulpopus
    last month

    but you can read the image's data here

    https://planted-cms.herokuapp.com/api/lms-media/


    this ^ is why i assumed the read access wouldnt be an issue

  • discord user avatar
    jmikrut
    Payload Team
    last month


    going to the access endpoint, i see an error



    shows me somewhere in some access control, there is something broken



    likely the cause here

    image.png
  • default discord avatar
    paulpopus
    last month

    interesting....

  • discord user avatar
    jmikrut
    Payload Team
    last month

    call me mr. detective



    good call

  • default discord avatar
    paulpopus
    last month

    i always assumed if you can read it, it passes but good to know to check ^

  • default discord avatar
    ethelien
    last month

    where does the access endpoint come from?



    The Media Collection for lms-media has these access rights


    export const acadamyAccess = {
      create: ({ req: { user } }): boolean => isAdmin(user) || isAcedemy(user) || isEditor(user),
      read: (): boolean => true,
      update: ({ req: { user } }): boolean => isAdmin(user) || isAcedemy(user) || isEditor(user),
      delete: ({ req: { user } }): boolean => isAdmin(user) || isAcedemy(user) || isEditor(user),
    };


    I have rechecked all of my collections but they all have public read access



    So I figured when I am logged in I can access the access route



    from the docs:


    The Access operation returns what a logged in user can and can't do with the collections and globals that are registered via your config. This data can be immensely helpful if your app needs to show and hide certain features based on access control, as the Payload Admin panel does.

    Does that not indicate that if a user is not logged in that the response will always be that error?



    @jmikrut Oh god dammit! You were right, I had an error in my Users Collection, after I fixed that the whole request worked as supposed



    Thank you guys

  • discord user avatar
    jmikrut
    Payload Team
    last month

    beautiful



    happy to hear it

  • default discord avatar
    ethelien
    last month

    I was a bit too eager on that one, only one of my collections spits out the actual image data, the other 2 don't so I am a bit confused because the access rights are the same



    And if I look into the access endpoint its fine too



    coming a bit closer: if I add more than 1 cloudinary image, only 1 of the images (the last added i think) gets populated, the rest does not



    it seems to be the image identifier when using different collections

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.