Hi @MutedJam, thank you for your answer.
I’ll try to explain the issue in greater detail.
Our implementation
How the Custom Fields component is made :
The Custom Fields component is a fixedCollection.
It is used to add or remove options
that lets the user choose a code corresponding to a Custom Field on the system.
The Custom Fields can have different types.
The type can be simple (boolean, string…) or complex (list, checkbox list…)
The user can choose one custom field among all of them by selecting its name from the Field Name or ID dropdown menu.
We use a single method on all Custom Fields (if they are a list) to get the list values.
It uses getNodeParameter()
to get the already loaded custom fields and to fetch the list values accordingly.
The problematic case :
Let’s consider the user has chosen two list custom fields he needs to interact with, list1
and list2
.
When fetching the list values, getNodeParameter()
returns :
{
customFieldsValues: [
{
code: 'LIST_1|LIST|VALUE_1,VALUE_2',
type: 'LIST',
listValue: []
},
{
code: 'LIST_2|LIST|VALUE_3,VALUE_4',
type: 'LIST',
listValue: []
}
]
}
The code
parameters holds 3 different pieces of information, separated by |
:
- The actual code used by the system (LIST_1, LIST_2…)
- The data type (LIST)
- The list values (VALUE_1, …)
The method that returns the list values reads the 3rd part of the code to know what are the relevant list values.
Since no argument can be passed to the method that returns the list values (in order to differentiate between the possible list values) it gets the last loaded custom field from these parameters and returns the list values accordingly.
Here is the `getCustomFieldListValues` method
async getCustomFieldListValues(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
//Get the customFields that have already been fetched, and return the listValues corresponding to the newest item
const returnData: INodePropertyOptions[] = [];
const customFieldsUI = this.getNodeParameter("customFieldsUI") as IDataObject;
if (customFieldsUI.customFieldsValues) {
//Convert the custom fields JS object to an array
const customFieldsArray = Object.entries(customFieldsUI.customFieldsValues);
//Convert the keys from strings to numbers, in order to be able to get the last element
const customFieldsArrayWithNumericKeys = customFieldsArray.map(([key,value])=>[+key,value]);
//Get the last element.
const lastCustomFieldEntry = customFieldsArrayWithNumericKeys.slice(-1)[0][1]
//The `code` holds data in the following pattern : CODE|TYPE(|LISTVALUES), with the listValues being comma-separated
const listValues = lastCustomFieldEntry.code.split("|")[2].split(",") as string;
//Return the list values
for (const value of listValues) {
returnData.push({
name: `${value}`,
value: `${value}`,
});
}
return returnData.sort((a, b) => a.name < b.name ? 0 : 1);
}
},
This method works fine when the user first adds the custom fields !
The issue
Since there can be multiple lists, an issue arises when the user refreshes a list that isn’t the last one that has been added.
If there are two lists, list1
and list2
:
when the user refreshes list1
, they get the list values for list2
, which is incorrect.
This makes Test list
have the list values options related to list 2
This is because of how getCustomFieldListValues
has been implemented.
This is why it would be nice to find another way to get the relevant custom field.
→ Do you think there is a way to get around this issue ?
Many thanks