Fixed value working - Expression not resolving

Hi,

So I have an issue with using expression as input in my custom declarative node.

Here is the issue:
I have tested my node using fixed value, without issues.

Here is my node:
image

It calls a webservice, and this node works fine.

But if I use an expression to get the value from the preivous node, it doesnt work eventhough it seems to resolve fine:
image

The value wowaAction* is added to the query body of my request in the node.

As you can see the string seems to resolve fine (to “Test2527”, same as the value I used for my tests as fixed value).

In my node, I use this expression to get the value:

"wowaAction": '={{$parameter.requestbody.wowaAction}}'

Which works fine when using fixed inputs.

Is there an issue there that prevents the expression from resolving before being added to the query ?

Thanks!

Information on your n8n setup

  • **n8n version:0.219.1
  • Running n8n via Docker

Hey @Alelf,

Have you checked other nodes to see what they do? The OpenAI node is a good example and will provide the answer you are answer and a solid example.

Can you please share a little bit more of what exactly you are doing. Generally does $parameter not resolve expressions, it returns the exact value a parameter is set to. In the declarative design you normally access only the value of the current parameter and do that via $value

Hi again,

Again thanks for the reactivity ^^.

My node is a bit complex but here’s the summary: I have an operation (in this case “POST”), which, when selected, shows a collection (Request Body), with various options as well as a string parameter (id10).

In my case the collection is RequestBody and the option in the collection is wowaAction.

On id10, I can access the value, fixed or expression, with no issues using ‘={{$parameter.id10}}’ but for the collection it seems to work only for Fixed values using ‘={{$parameter.RequestBody.wowaAction}}’)

So to sum up I have no issues with a fixed value to access options of the collection, but if I put an expression it takes the expression itself (so if I put {{“Test”}} it will write “={{“Test”}}” in the request, instead of “Test”, but if I write the fixed value “Test”, it correctly puts “Test”.

Also just to add a bit of context I am trying to access these parameters to populate the body of my request.

Sadly still not sure I understand.

Normally you would just do that:

{
	displayName: 'My Parameter',
	name: 'myParameter',
	type: 'string',
	routing: {
		send: {
			property: 'id10',
			type: 'body',
		},
	},
	default: '',
},

Which will then send the value (whatever it is, fixed or expression) as “id10” in the body.

If you really need to do something more complex like transforming the value (like convert it to upper case) you would do:

{
	displayName: 'My Parameter',
	name: 'myParameter',
	type: 'string',
	routing: {
		request: {
			body: {
				id10: '={{ $value.toUpperCase() }}',
			},
		},
	},
	default: '',
},

$parameter should generally never be used in the declarative design. Just realized that we have it for some reason in the docs as example which really has to get changed.

Hi,

Yeah indeed I’ve relied on $parameter quite a bit.

My issue is that I put multiple parameters in my body so I have to access other properties to build it.

So for example. This works fine:

	{
		displayName: 'My method',
		name: 'method',
		type: 'string',
		routing: {
			request: {
				body: {
					id10: '={{ $parameter.id10 }}',
				},
			},
		},
		default: 'POST',
	},
		displayName: 'My Parameter',
		name: 'id10',
		type: 'string',
		default: '',
	},

But this works only with fixed values:

	{
		displayName: 'My method',
		name: 'method',
		type: 'string',
		routing: {
			request: {
				body: {
					param1: '={{ $parameter.options.param1}}',
				},
			},
		},
		default: 'POST',
	},
		displayName: 'My Parameter',
		name: 'id10',
		type: 'string',
		default: '',
	},{
		displayName: 'Options',
		name: 'options',
		type: 'collection',
		placeholder: 'Add Option',
		default: {},
		options: [
			{
				displayName: 'Parameter of request body',
				name: 'param1',
				type: 'string',
				default: '',
				description: 'test'
				`,
			},
		],
	},

Is there any way to access param1 for the body of the request in a declarative node ? That being said if I shouldn’t use $parameter at all I might have to revert to a programmatic node after all.

Do I understand correctly that the problem is that you either want to send the data in body or query depending on the setting?

Hi,

No ^^.

I always send the data in the body. The issue is that when the parameter I try to get at is in a collection, and I put an expression in the node as input, the expression is not resolved.

So $parameter.id10 works, and resolve the expression in the node if there is one. So it converts {{2*5}} to 10.
But ‘={{ $parameter.options.param1}}’ only works with fixed values, if I put a expression it’s not resolved.

Basically my issue is simply with the fact that $parameter.X.Y doesn’t resolve an expression (where X is a collection and Y an option of that collection) but $parameter.X does (where X is simply a string property of the node). So when I try to get to the string parameter Y in the collection X, it only works with fixed values.

In my example above the collection is “options” and the parameter is “param1”. And I try to send $parameter.options.param1 in the body; but this only works if I put a fixed values in the node. If I put an expression {{25}} in the node it puts "=25" in the body, instead of 10, the result of the expression. Same issue if I try to put the output of a previous node in param1.

In this case what I wrote above still holds true. You would not use $parameter. You rather define what to send and how to send it on the paramter itself.

So your above example would rather look like this:

{
	displayName: 'My method',
	name: 'method',
	type: 'string',
	default: 'POST',
},
{
	displayName: 'My Parameter',
	name: 'id10',
	type: 'string',
	default: '',
	routing: {
		send: {
			property: 'id10',
			type: 'body',
		},
	},
},
{
	displayName: 'Options',
	name: 'options',
	type: 'collection',
	placeholder: 'Add Option',
	default: {},
	options: [
		{
			displayName: 'Parameter of request body',
			name: 'param1',
			type: 'string',
			default: '',
			description: 'test',
			routing: {
				send: {
					property: 'param1',
					type: 'body',
				},
			},
		},
	],
},
1 Like

That works perfectly. Sorry I had a bad understanding of the routing, I didnt realize it adds up and thought the body had to be defined all together in one property.

Thanks a lot for the quick help!

Makes sense. Happy to hear that it was helpful.

Have fun!

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