Return of afterRead hook for relationship field

default discord avatar
thebergamo
10 months ago
1 1

Hi there :)

Here I'm with another question...

What is the expected return in the afterRead hook?

Not sure if my configuration is wrong or something, but I created a field inside a block that based on some other field this should be populated in the API call.

This is my example:

import payload from "payload";
import { Block, FieldHook } from "payload/types";
import { Type as MediaType } from "../../collections/Media";
import { Type as TagType } from "../../collections/Tags";

export type Type = {
  blockType: "media";
  blockName?: string;
  media: MediaType[];
  tag: TagType[];
};

const afterReadHook: FieldHook<any, string[], any> = async (
  args
): Promise<string[]> => {
  const { value, siblingData, data, req } = args;

  if (req.user?.collection === "users") {
    return value;
  }

  console.log({ siblingData, value });
  const media = await payload.find({
    collection: "media",
    where: {
      tags: {
        in: siblingData.tag.join(","),
      },
    },
  });

  console.log({ media: media.docs });

  return media.docs.map(({ id }) => id);
};

export const MediaList: Block = {
  slug: "mediaList",
  labels: {
    singular: "Media List Block",
    plural: "Media List Blocks",
  },
  fields: [
    {
      name: "tag",
      label: "Tag",
      type: "relationship",
      relationTo: "tags",
      hasMany: true,
      required: true,
    },
    {
      name: "media",
      label: "Media",
      type: "relationship",
      relationTo: "media",
      hasMany: true,
      admin: {
        disabled: true,
      },
      hooks: {
        afterRead: [afterReadHook],
      },
    },
  ],
};

In this case, I would like to fetch all media with given tags specified in the field tag and return in the field media when this API is called.

As of now, it only works if in the return of afterRead hook I return an array of ids, but then it's not getting populated automatically.

Is it a valid use case for Payload or some of my code/configurations are wrong in this case?

  • discord user avatar
    jacobsfletch
    Payload Team
    8 months ago

    @thebergamo the afterRead hook should return a modified document. For reference, here's the types for that hook:

    and here are the related docs: https://payloadcms.com/docs/hooks/fields#field-hooks

    So your hook should look something like this (not tested):

    const afterReadHook: FieldHook<any, string[], any> = async (
      args
    ): Promise<string[]> => {
      const { doc, req } = args;
    
      if (req.user?.collection === "users") {
        return doc;
      }
    
      const media = await payload.find({
        collection: "media",
        where: {
          tags: {
            in: doc.tag.join(","),
          },
        },
      });
    
      return {
        ...doc,
        media: media.docs.map((doc) => doc.id),
      }
    };
Open the post
Continue the discussion in GitHub
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.