Hi,
as there are some threads about the relationship & afterRead hook matter I'd like to share my findings:
Related Threads:
The relationship field:
relationTo: 'collection-slug'
and value: 'collection-id'
The afterRead hook...
If we want to modify the value of the relationship field when it's queried (which means in the afterRead hook), we face the following issue:
We need to include the original relationship data when the admin UI reads the field (otherwise it breaks).
But if we include relationTo
and value
properties, the relationship field is going to be populated automatically.
The solutions is:
maxDepth: 0
which practically disables the automatic population of the field.const relationshipField = {
type: 'relationship',
name: 'internal',
label: 'Document to link to',
relationTo: ['pages'],
required: true,
maxDepth: 0, // <-- important
hooks: {
afterRead: [
(args) => extractFieldsFromRelationship(args, ['url'])
]
}
}
async function extractFieldsFromRelationship(args, topLevelFields = []) {
// afterRead
if (typeof args.value === 'undefined') return
const refCollection = args.value.relationTo
const refID = args.value.value
const doc = await payload.findByID({
collection: refCollection,
id: refID,
depth: 1,
})
const extract = {}
topLevelFields.map(field => {
if (doc[field]) extract[field] = doc[field]
})
// include this - otherwise the admin UI will not work properly
extract.relationTo = refCollection
extract.value = refID
//return doc // This is the default way. The whole doc is included.
return extract
}
@unonweb this is great!! The only thing that jumps out at me are that it seems like you should not have to set maxDepth: 0
— because this requires you to make that extra query from within your hook. The entire document is already present in the args, so couldn't you just strip out the irrelevant fields without querying your relationship again?
That first discussion you linked has some pretty good information, for others who stumble by. Namely, doing this will break GraphQL, and that this is really where GraphQL shines.
Thank you for this thorough example!
Thanks for that tip!
Also related, solves that really elegantly: #1288
I think using REST has a lot of benefits over GraphQL for certain cases, but it's currently handicapped by the relationships because of this select issue, also when using an internal link inside the Rich Text for example.
Star
Discord
online
Get dedicated engineering support directly from the Payload team..