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.

How to select specific fields of related nested object in local Payload CMS Local API?

default discord avatar
.commadotlast year
4

I have the following collections:


export const Media: CollectionConfig = {
  slug: 'media',
  fields: [
    { name: 'alt', type: 'text' },
  ],
  upload: true,
}

export const Author: CollectionConfig = {
  slug: 'authors',
  fields: [
    { name: 'name', type: 'text' },
    { name: 'bio', type: 'text' },
    { name: 'avatar', type: 'upload', relationTo: 'media' },
  ],
}

export const Genre: CollectionConfig = {
  slug: 'genres',
  fields: [
    { name: 'name', type: 'text' },
    { name: 'description', type: 'text' },
  ],
}

export const Book: CollectionConfig = {
  slug: 'books',
  fields: [
    { name: 'title', type: 'text' },
    { name: 'genre', type: 'relationship', relationTo: 'genres' },
    { name: 'author', type: 'relationship', relationTo: 'authors' },
    { name: 'cover', type: 'upload', relationTo: 'media' },
  ],
}


When I query books with

depth: 2

, I get all fields from the related collections:


const books = await payload.find({
  collection: 'books',
  depth: 2,
  select: {
    title: true,
    genre: true,
    author: true,
    cover: true,
  },
})


What I want to achieve:


I only want to get:


- Book title


- Genre name (only the name, not description)


- Author name and avatar URL (only these fields, not bio)


- Cover image URL (only the URL, not alt or other fields)



Is there a way to specify which fields to select from nested relationships in local api?

Current object structure:


{
  id: 2,
  title: "The Great Novel",
  genre: {
    id: 27,
    name: "Fiction",
    description: "Fiction books and novels",
    createdAt: "2024-12-29T16:17:17.763Z",
    updatedAt: "2024-12-29T16:17:17.763Z"
  },
  author: {
    id: 15,
    name: "Jane Smith",
    bio: "Award-winning author with 20 years of experience...",
    avatar: {
      id: 45,
      alt: "Jane Smith profile",
      filename: "jane-smith.webp",
      filesize: 52140,
      width: 512,
      height: 512,
      mimeType: "image/webp",
      url: "/api/media/file/jane-smith.webp",
      thumbnailURL: null,
      createdAt: "2024-12-29T16:17:17.909Z",
      updatedAt: "2024-12-29T16:17:17.909Z"
    },
    createdAt: "2024-12-29T16:17:17.763Z",
    updatedAt: "2024-12-29T16:17:17.763Z"
  },
  cover: {
    id: 27,
    alt: "Book Cover",
    filename: "great-novel.webp",
    filesize: 75260,
    width: 1024,
    height: 1024,
    mimeType: "image/webp",
    url: "/api/media/file/great-novel.webp",
    thumbnailURL: null,
    createdAt: "2024-12-29T16:17:17.909Z",
    updatedAt: "2024-12-29T16:17:17.909Z"
  },
  createdAt: "2025-01-02T16:22:20.760Z",
  updatedAt: "2025-01-02T16:22:20.760Z"
}


Desired response structure:


{
  id: 2,
  title: "The Great Novel",
  genre: {
    name: "Fiction"
  },
  author: {
    name: "Jane Smith",
    avatar: {
      url: "/api/media/file/jane-smith.webp"
    }
  },
  cover: {
    url: "/api/media/file/great-novel.webp"
  },
  createdAt: "2025-01-02T16:22:20.760Z",
  updatedAt: "2025-01-02T16:22:20.760Z"
}
  • default discord avatar
    reepicheep05.last year

    Yes! You can use the

    populate

    option in the

    payload.find

    call.



    await payload.find({
      collection: 'books',
      depth: 2,
      select: {
        title: true,
        genre: true,
        author: true,
        cover: true,
      },
      populate: {
        genre: {
          title: true
        },
        ...
      }
    })


    Or if makes more sense, you set the default to load only the title using

    defaultPopulate

    on the related collections.



    genre.ts


    defaultPopulate: {
      title: true
    }
  • default discord avatar
    .commadotlast year

    @reepicheep05 , thank you very much! It helped!



    Tried with

    defaultPopulate

    on

    Media

    now I see only

    id

    ,

    alt

    and

    url

    as I want.



    However, for some reason the

    url

    field is

    null

    ,

    alt

    has the correct value.



    In the API preview in the admin dashboard I see the correct "/api/media/file/image.webp", so it is definitely not

    null

    🤷‍♂️

  • default discord avatar
    reepicheep05.last year

    Oh yeah, I think you have to include the

    filename

    field so that it can generate the url. Or you could set up a virtual field and populate that instead.

  • default discord avatar
    zed0547last year

    Correct, with media you need to include the filename for it to generate the url as expected



    See the note in docs here:

    https://payloadcms.com/docs/queries/select#defaultpopulate-collection-config-property
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.