Question

Create a parent-child relationship between two triggers

  • 27 June 2023
  • 7 replies
  • 87 views

Badge +1

I have two triggers, get_entity and get_project, that I’d like relate in a parent-child hierarchy.  I’ve tried to adapt X for my needs.

I created the get_entity trigger:

const perform = async (z, bundle) => {    
return [
{ id: 1, name: 'Entity 1' },
{ id: 2, name: 'Entity 2' }
];
};

module.exports = {
operation: {
perform: perform,
outputFields: [
{ key: 'id', type: 'integer' },
{ key: 'name', type: 'string' },
],
},
display: {
description: 'Get a list of entities.',
hidden: true,
label: 'Get Entities',
},
key: 'get_entity',
noun: 'Entity',
};

I created the get_project trigger:

const perform = async (z, bundle) => {
const e1 = [
{ id: 1, name: 'E1 - P1' },
{ id: 2, name: 'E1 - P2' }
];
const e2 = [
{ id: 1, name: 'E2 - P1' },
{ id: 2, name: 'E2 - P2' }
];

return bundle.inputData.entity_id == 1 ? e1 : e2;
};

module.exports = {
operation: {
perform: perform,
inputFields: [
{
key: 'entity_id',
label: 'Entity ID',
type: 'integer',
required: true,
dynamic: 'get_entity.id.name',
},
],
outputFields: [
{ key: 'id', type: 'integer' },
{ key: 'name', type: 'string' },
],
},
display: {
description: 'Get a list of projects.',
hidden: true,
label: 'Get projects',
},
key: 'get_project',
noun: 'Project',
};

I created the lorem_ipsum action:

const perform = async (z, bundle) => {
return {id: 1, name: 'Lorem Ipsum'};
};

module.exports = {
display: {
description: 'lorem ipsum',
hidden: false,
label: 'Lorem Ipsum',
},
key: 'lorem_ipsum',
noun: 'Lorem',
operation: {
inputFields: [
{
key: 'project_id',
label: 'project',
type: 'integer',
dynamic: 'get_project.id.name',
required: true,
list: false,
altersDynamicFields: false,
},
],
outputFields: [
{ key: 'id' },
{ key: 'name' },
],
perform: perform,
},
};

I created a Zap and added my Lorem Ipsum action.  When I try to select a project, I get this error:

 

What am I not understanding?


7 replies

Userlevel 3
Badge +6

👋 Hey @benjamink9 ,

Am I correctly understanding that the goal is the following flow?

  1. User selects an entity
  2. Depending on the entity selected, show different dropdown options in the Project field

If so, the issue currently appears to be that there’s no way to map the entity_id field in the hidden get_project trigger.

Instead, I might suggest trying the following:

  • Remove the entity_id field from the get_project trigger
  • Paste the entity_id field into the lorem_ipsum action so the action has two fields, one for entity and one for project
  • Add altersDynamicFields: true to entity_id so the project field is recomputed when entity_id changes

This way, when the user selects an entity from the entity field, the bundle will include the value the that the project field needs to run its perform and return the corresponding dropdown choices.

The action might then look something like the following:

const perform = async (z, bundle) => {
return {id: 1, name: 'Lorem Ipsum'};
};

module.exports = {
display: {
description: 'lorem ipsum',
hidden: false,
label: 'Lorem Ipsum',
},
key: 'lorem_ipsum',
noun: 'Lorem',
operation: {
inputFields: [
{
key: 'entity_id', // copied over from get_project
label: 'Entity ID',
type: 'integer',
required: true,
dynamic: 'get_entity.id.name',
altersDynamicFields: true // new
},
{
key: 'project_id',
label: 'project',
type: 'integer',
dynamic: 'get_project.id.name',
required: true,
list: false,
altersDynamicFields: false,
},
],
outputFields: [
{ key: 'id' },
{ key: 'name' },
],
perform: perform,
},
};

Apologies if I’ve misunderstood, but I hope this is a step in the right direction.

Badge +1

That worked:

 

It would be nice to be able to define this in the trigger itself--better encapsulation.


Thanks for the help.

Badge +1

I actually need to use the parent (entity_id) to restrict multiple children (project, department, location).  I think I would need to have multiple references to entity_id in the action, one for each child.

Will your approach work for this?

Userlevel 3
Badge +6

Yes, I think the same approach should work, although, as you mentioned, you might need to modify the references based on what fields depend on each other.

Badge +1

Using the entity_id repeatedly didn’t work--each input needs to have a unique name.  Is there another approach?

Userlevel 3
Badge +6

Hey @benjamink9 , great catch!

Yes, each field needs to have a unique key.

I apologize, but I’m having a bit of trouble picturing the current implementation. Could you please share a snippet of your code?

Badge +1

Currently, I have three triggers:

get_legal_entities:

const perform = async (z, bundle) => {
const options = {
url: 'https://apis.paycor.com/v1/legalentities/ActivatedLegalEntityTenantList',
method: 'GET',
headers: {
Accept: 'application/json',
'Ocp-Apim-Subscription-Key': bundle.authData.subscription_key,
Authorization: `bearer ${bundle.authData.access_token}`,
},
};

return z.request(options).then((response) => {
response.throwForStatus();
const results = response.json;

// becasue Zapier requires that each array element have an id property
results.userLegalEntities.forEach(element => {
element.id = element.legalEntityId
});

return results.userLegalEntities;
});
};

get_work_locations:

const perform = async (z, bundle) => {
const options = {
url: `https://apis.paycor.com/v1/legalentities/${bundle.authData.legal_entity_id}/worklocations`,
method: 'GET',
headers: {
Accept: 'application/json',
'Ocp-Apim-Subscription-Key': bundle.authData.subscription_key,
Authorization: `bearer ${bundle.authData.access_token}`,
},
};

return z.request(options).then((response) => {
response.throwForStatus();
const results = response.json;

return results.records;
});
};

and

get_job_titles:

const perform = async (z, bundle) => {
const options = {
url: `https://apis.paycor.com/v1/tenants/${bundle.authData.legal_entity_id}/jobtitles`,
method: 'GET',
headers: {
Accept: 'application/json',
'Ocp-Apim-Subscription-Key': bundle.authData.subscription_key,
Authorization: `bearer ${bundle.authData.access_token}`,
},
};

return z.request(options).then((response) => {
response.throwForStatus();
const results = response.json;

// becasue Zapier requires that each array element have an id property
results.records.forEach(element => {
element.id = element.JobTitleId
});

return results.records;
});
};

Currently,I get the legal_entity_id from the authentication script:

    {
computed: false,
key: 'legal_entity_id',
required: true,
label: 'Legal Entity Id',
type: 'string',
helpText: 'LegalEntityId = ClientID',
},

These triggers are referenced by two inputs in create_employee action:

      {
key: 'WorkLocation',
label: 'Work Location',
type: 'integer',
dynamic: 'get_work_locations.id.name',
required: false,
list: false,
altersDynamicFields: false,
helpText: 'The name of the Work Location to associate with new hire.'
},
{
key: 'JobTitle',
label: 'Job Title',
type: 'string',
dynamic: 'get_job_titles.JobTitle',
required: false,
list: false,
altersDynamicFields: false,
helpText: "The employee's job title."
},

What I want to be able to include a reference to the get_legal_entity trigger, such that I can use the bundle.inputData.legal_entity_id, rather than bundle.authData.legal_entity_id (I don’t want to hard code this value in the auth settings).  Unfortunately, I haven’t been able to get this to work.

Any suggestions?

Reply