@@ -40,7 +40,7 @@ export class DynamicNode implements INodeType {
4040 name : 'doNotWaitToFinish' ,
4141 type : 'boolean' ,
4242 default : false ,
43- description : 'Whether to return immediately after starting the sub-workflow' ,
43+ description : 'Return immediately after triggering the sub-workflow. Advanced: disables result collection. ' ,
4444 } ,
4545 ] ,
4646 } ;
@@ -87,6 +87,32 @@ export class DynamicNode implements INodeType {
8787 ? baseNode . position
8888 : [ 240 , 0 ] ;
8989
90+ // Evaluate top-level parameters
91+ for ( const key of Object . keys ( nodeClone . parameters ) ) {
92+ const value = nodeClone . parameters [ key ] ;
93+ if ( typeof value === 'string' && value . includes ( '{{' ) ) {
94+ try {
95+ nodeClone . parameters [ key ] = await this . evaluateExpression ( value , item , index ) ;
96+ } catch ( err ) {
97+ this . logger . warn ( `DynamicNode: Failed to evaluate parameter '${ key } ': ${ err instanceof Error ? err . message : String ( err ) } ` ) ;
98+ }
99+ }
100+ }
101+
102+ // Evaluate nested body parameters
103+ const bodyParams = nodeClone . parameters ?. bodyParameters ?. parameters ;
104+ if ( Array . isArray ( bodyParams ) ) {
105+ for ( const param of bodyParams ) {
106+ if ( typeof param . value === 'string' && param . value . includes ( '{{' ) ) {
107+ try {
108+ param . value = await this . evaluateExpression ( param . value , item , index ) ;
109+ } catch ( err ) {
110+ this . logger . warn ( `DynamicNode: Failed to evaluate body param '${ param . name } ': ${ err instanceof Error ? err . message : String ( err ) } ` ) ;
111+ }
112+ }
113+ }
114+ }
115+
90116 template . nodes . push ( nodeClone ) ;
91117 template . connections . Start . main [ 0 ] [ 0 ] . node = nodeClone . name ;
92118
@@ -95,38 +121,28 @@ export class DynamicNode implements INodeType {
95121 const execResult = await this . executeWorkflow (
96122 { code : template } ,
97123 [ item ] ,
98- {
99- contextData : {
100- $data : item . json ,
101- $json : item . json ,
102- } ,
103- } ,
124+ { } ,
104125 {
105126 parentExecution : {
106127 executionId : workflowProxy . $execution . id ,
107128 workflowId : workflowProxy . $workflow . id ,
108129 } ,
109- doNotWaitToFinish : doNotWaitToFinish ,
110- itemIndex : 0 ,
111- } as any ,
130+ doNotWaitToFinish,
131+ } ,
112132 ) ;
113133
114134 if ( ! doNotWaitToFinish && execResult ) {
115- if ( Array . isArray ( execResult ) ) {
116- const flattened = execResult
117- . flat ( )
118- . filter ( ( entry : unknown ) : entry is INodeExecutionData => entry !== null && typeof entry === 'object' ) ;
119- allResults . push ( ...flattened ) ;
120- } else if (
121- typeof execResult === 'object' &&
122- 'data' in execResult &&
123- Array . isArray ( ( execResult as any ) . data )
124- ) {
125- const flattened = ( execResult as any ) . data
126- . flat ( )
127- . filter ( ( entry : unknown ) : entry is INodeExecutionData => entry !== null && typeof entry === 'object' ) ;
128- allResults . push ( ...flattened ) ;
129- }
135+ const resultArray = Array . isArray ( execResult )
136+ ? execResult
137+ : Array . isArray ( ( execResult as any ) . data )
138+ ? ( execResult as any ) . data
139+ : [ ] ;
140+
141+ allResults . push (
142+ ...resultArray . flat ( ) . filter ( ( entry : unknown ) : entry is INodeExecutionData =>
143+ entry !== null && typeof entry === 'object' ,
144+ ) ,
145+ ) ;
130146 }
131147 } ;
132148
@@ -139,7 +155,7 @@ export class DynamicNode implements INodeType {
139155 }
140156 }
141157 } else {
142- // Run one sub-workflow with all items
158+ // One execution for all items (rare)
143159 const template = JSON . parse ( JSON . stringify ( subWorkflowTemplate ) ) ;
144160 const nodeClone = JSON . parse ( JSON . stringify ( baseNode ) ) ;
145161
@@ -168,21 +184,17 @@ export class DynamicNode implements INodeType {
168184 ) ;
169185
170186 if ( ! doNotWaitToFinish && execResult ) {
171- if ( Array . isArray ( execResult ) ) {
172- const flattened = execResult
173- . flat ( )
174- . filter ( ( entry : unknown ) : entry is INodeExecutionData => entry !== null && typeof entry === 'object' ) ;
175- allResults . push ( ...flattened ) ;
176- } else if (
177- typeof execResult === 'object' &&
178- 'data' in execResult &&
179- Array . isArray ( ( execResult as any ) . data )
180- ) {
181- const flattened = ( execResult as any ) . data
182- . flat ( )
183- . filter ( ( entry : unknown ) : entry is INodeExecutionData => entry !== null && typeof entry === 'object' ) ;
184- allResults . push ( ...flattened ) ;
185- }
187+ const resultArray = Array . isArray ( execResult )
188+ ? execResult
189+ : Array . isArray ( ( execResult as any ) . data )
190+ ? ( execResult as any ) . data
191+ : [ ] ;
192+
193+ allResults . push (
194+ ...resultArray . flat ( ) . filter ( ( entry : unknown ) : entry is INodeExecutionData =>
195+ entry !== null && typeof entry === 'object' ,
196+ ) ,
197+ ) ;
186198 }
187199 }
188200
0 commit comments