Add and remove properties dynamically

Hey!

I need to create a node with a fixed property template as options and other dynamic properties that depend on the value of this template

description: INodeTypeDescription = {
		displayName: 'Promptify',
		name: 'promptify',
		group: ['transform'],
		version: 1,
		description: 'Basic Promptify Node',
		defaults: {
			name: 'Promptify',
		},
		inputs: ['main'],
		outputs: ['main'],
		properties: [
			{
				displayName: 'Templates',
				name: 'template',
				type: 'options',
				default: '',
				placeholder: 'Choose a template',
				description: 'Choose a template and start generating',
				typeOptions: {
					loadOptionsMethod: 'getTemplates'
				}
			},
			{
				displayName: 'Inputs',
				name: 'inputs',
				type: 'json',
				default: '',
				placeholder: 'Template Inputs',
				description: 'Inputs to be used',
				typeOptions: {
					loadOptionsDependsOn: ['template'],
					loadOptionsMethod: 'getInputs',
				}
			},
		],
	};

Inside getInputs I can get the template value and fetch API data based on it. based on this fetched data I need to display questions as properties/inputs. These questions are different from one template to another.

I know that I can control the display of properties using the show attribute or make a property loadOptionsDependsOn, but that’s not exactly my use case, because I can’t control or predict the fetched properties’ names/types…etc.

Thanks.

Hi @SALMAN, welcome to the community!

Perhaps @marcus from our node engineering team can help with this one?

Thanks @MutedJam,

@marcus, If you can direct me on how I can handle this use case and is it possible?

Also, as a workaround, if adding new properties’ not possible, is if I could mutate an already there json property and add these questions in json format { question: "...", answer: "..." }

For anyone with the same needs for dynamic inputs. You should use resourceMapper to list your inputs:


			{
				displayName: 'Inputs',
				name: 'inputs',
				type: 'resourceMapper',
				noDataExpression: true,
				default: {
					mappingMode: 'defineBelow',
					value: null,
				},
				required: true,
				typeOptions: {
					loadOptionsDependsOn: ['template'],
					resourceMapper: {
						resourceMapperMethod: 'getInputs',
						mode: 'update',
						fieldWords: {
							singular: 'input',
							plural: 'inputs',
						},
						addAllFields: true,
						multiKeyMatch: true,
					},
				},
			},

Inside Node class methods attributes you should define the getInputs as:


	methods = {
		resourceMapping: {
			getInputs
		},
	};

And getInputs should be using ResourceMapperFields for returning your fields:

export async function getInputs(this: ILoadOptionsFunctions): Promise<ResourceMapperFields> {
	const inputs  = ...howeveryougetinputs;

	return {
		fields: inputs.map(input => (
			{
				id: input.name,
				displayName: input.fullName,
				defaultMatch: true,
				canBeUsedToMatch: true,
				required: input.required,
				display: true,
				type: input.type,
			}
		))
	}
}
2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.