#Getting Relationship collection selected option name for conditionally displaying other fields

26 messages · Page 1 of 1 (latest)

ivory jay
#

Trying to figure out the most performant way to go about this - I have a collection (with autosave enabled) that includes a relationship field to a different collection. Every time the user changes the dropdown selection for the relationship field, I need to show or hide specific fields (I had been setting that using admin->condition). The part I'm getting stuck on is that I want to check the condition based on the name of the relationship collection field, not the ID, but to do that I have to go get the value. I was playing around with an afterRead hook, but I think that is going to cause performance issues with findByID (to get relationship value name) in afterRead, firing all the time...

ivory jay
#

I had been trying to get the name value from the collection in an afterRead hook and save it to a virtual+disabled field, then grab the value from there to check it when evaluating condition, like this

#

afterRead: [
async({doc, req}) => {

    if(doc.segment){
      
      const segmentID = doc.segment.id ?? doc.segment
      
      const segmentQuery = await req.payload.findByID({
          collection: 'segment',
          id: segmentID,
          req,
      })
      doc.segmentName = segmentQuery?.name
        
    }
    return doc
}

]
.....

{
name: 'internshipName',
type: 'text',
required: true,
admin: {
condition: (data) => {
if(data.segmentName==="Internships")
return true;
return false}
},
},
{
name: 'segment',
label: 'Segment',
type: 'relationship',
relationTo: 'segment',
},
{
name:'segmentName',
type:'text',
virtual:true,
admin:{ disabled: true },
},

#

Originally this seemed like it was working fine, but now I'm seeing the afterRead hook is getting fired after the condition is evaluated, so that defeats the purpose. I must have changed something but I'm not sure what 🙁

#

Regardless of that, I think this is probably not the best way to solve this

#

@versed geode any suggestions?

versed geode
#

Can you share your full collection config

#

Why not just do the check within the condition function itself? Fetch the doc there

#

I rarely recommend, or use myself, the afterRead hook

ivory jay
versed geode
#

Your segment name is virtual

#

So it saves no data and will be empty when yo utry t oread it in a condition check

#

For virtual fields you should use afterRead

#

Or, make it non-virtual and populate it in a beforeChange hook

#

And have it ready there for your condition check

ivory jay
versed geode
#

Yeah, what I mean is by virtue of the field being virtual, you must use an afterRead to actually populate the field

#

Instead of making it a virtual field, why not let it actually hold data - no afterRead required

#

Instead you move this population logic into a beforeChange hook

#

It runs once and not on every read in that way

ivory jay
#

Gotcha. Yeah, that makes sense and definitely better performance than setting on every read.

#

Related question though - admin {condition } is evaluated prior to afterRead hook? The docs state that the hook "Runs as the last step before documents are returned. "

versed geode
#

afterReads get evaluated as the last step before data is sent to the requester. The condition function gets data at adepth of 0 as a baseline I think due to performance

ivory jay
#

I see.
Thanks!

versed geode
#

My pleasure!