Currently I have a Media collection that can accept upload.mimeTypes: ['image/
', 'video/']
I have an Article collection that has a relationship to media. In the article collection I want to conditionally display fields using admin.condition based on if the mime type of the Media doc that is selected.
Is this possible? The selected media's data is the media _id instead of the media doc as a whole. Is there a place I should write an api query to power admin.conditions for the fields i want to conditionally show on Articles?
yep I completely understand what your describing here, your media field is a relationship to an upload, which is just a reference to an id and not the full doc. What you need to do is fetch the full doc—but you should not make
admin.conditionasync because this function is run very frequently and this would not be performant. Instead, use another field named
mimeTypeor similar, then in an
afterChangehook on your collection, fetch the full doc and save its mime-type to that field. This way it only makes the request once when the document is created or updated, and that data is now passed through to your condition as expected. What do you think?
Awesome, this makes sense and I have tried this approach before posting here.
Do you have any examples of this flow?
I've tried what you described but I'm having trouble getting the afterChange hook to fire (I'm assuming I would see logs from it in my browser console when fired). Here is a snippet of my collection.
const afterMediaChange: FieldHook = (args) => {
console.log('afterMediaChange', args);
return '';
};
const articles: CollectionConfig = {
slug: 'articles',
fields: [
// ....
{
name: 'heromedia',
label: 'Hero Media',
type: 'relationship',
relationTo: 'media',
hasMany: false,
hooks: {
afterChange: [afterMediaChange],
},
},
]
}Must I fully type the generics in FieldHook for this to work?
Hmm this looks correct to me. Are you saving the document to trigger the hook? Fully typing the field hook wouldn't change anything here. Did your server restart after making this change? Try to throw a collection-level hook in here and see if that fires.
Oh its on save? I thought it was when selecting a new doc from the relationship. I've just been changing the value and I haven't been saving.
Yep 👍 and that's deliberate to avoid making many network requests
beforeChangewould work better here, too
Got it. That adds a step for the use case in this flow. I might take a different approach then. Thanks for the info and help!
You could alternatively use a custom component that watches that field, makes the request on every change, and returns the mime-type
In your custom component you'd fire the
useFormFieldshook to subscribe to the relationship, then use that value as a dependency of a
useEffectthat makes the request, something like this (not tested):
...
const [mimeType, setMimeType] = useState<string>();
const { value: mediaID } = useFormFields(([fields, dispatch]) => fields.media);
useEffect(() => {
const makeReq = async () => {
const req = await fetch(`${YOUR_SERVER_URL}/media/${mediaID}`)
const json = await req.json();
if (json.mimeType) {
setMimeType(json.mimeType)
}
}
}, [mediaID]);
if (mimeType.startsWith('image/')) {
return (
...
)
}
return null;ah i see, that makes sense too.
Star
Discord
online
Get dedicated engineering support directly from the Payload team.