Fix Loop Tutorial remove duplicated braces#2804
Conversation
… property.res %>` for better consistency.
📝 WalkthroughWalkthroughModified a YAML orchestration template file to change JSON output formatting. The aggregated result is now embedded using a templating expression instead of being wrapped in an array literal, altering how the Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
distribution/tutorials/orchestration/50-Loop-get-Details.yaml (2)
32-38:⚠️ Potential issue | 🟡 Minor
property.resisnullwhen the product list is empty.The
property.res ?: []guard initializes the list only on the first loop iteration. If the upstream API returns an empty$.productsarray, theforloop body never runs, andproperty.resremainsnull.<%= property.res %>then emitsnull, yielding"products": nullinstead of"products": [].🛡️ Proposed fix to initialize `property.res` before the loop
Initialize
property.resunconditionally before theforstep, e.g. with a groovy step or by extending the existing one:- request: # Fetch a list of products without price information - call: url: https://api.predic8.de/shop/v2/products?limit=7 + # Initialise the result accumulator so it is always a list + - groovy: + src: property.res = [] # Iterate over the products array in the response - for:Then the guard inside the loop can be simplified:
- property.res = property.res ?: [] - property.res.add( + property.res.add(🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@distribution/tutorials/orchestration/50-Loop-get-Details.yaml` around lines 32 - 38, The issue is that property.res may stay null when the upstream $.products array is empty because the groovy block only initializes it inside the loop; pre-initialize property.res to an empty list before the for loop (e.g., add a groovy step that sets property.res = property.res ?: []) so the output becomes [] instead of null, and then simplify the existing groovy loop body to just property.res.add(...) (remove the conditional initialization there). Ensure the pre-init step runs unconditionally prior to the for step that iterates over $.products and that the loop continues to use fn.jsonPath('$.price') as before.
40-46:⚠️ Potential issue | 🟠 MajorFix
<%= property.res %>to properly serialize the list as JSON.The
templatestep uses Groovy'sStreamingTemplateEngine, where<%= expr %>callstoString()on the expression result. A GroovyList<Map>renders as[[name:Product A, price:9.99]]— with unquoted map keys — which is not valid JSON.Similar tutorial files handle this correctly:
60-SOAP-Array-to-JSON.yamland20-Json-Transformation.yamlboth use.collect()to explicitly build JSON-serializable map structures within the template. Line 45 should follow the same pattern.Either transform the data within the template using
.collect()to construct proper JSON objects, or use explicit JSON serialization:Option 1: Build JSON structure in template (consistent with other tutorials)
- "products": <%= property.res %> + "products": <%= property.res.collect { item -> [ + "name": item.name, + "price": item.price + ] } %>Option 2: Explicit JSON serialization (if JsonOutput is available in template context)
- "products": <%= property.res %> + "products": ${groovy.json.JsonOutput.toJson(property.res)}Verify the actual output with a live test before merging.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@distribution/tutorials/orchestration/50-Loop-get-Details.yaml` around lines 40 - 46, The template is inserting property.res with Groovy's StreamingTemplateEngine which calls toString() and produces invalid JSON; update the template content where "<%= property.res %>" is used so the expression either (a) maps/collects property.res into JSON-serializable maps/values (use property.res.collect to build plain maps with string keys for each product) or (b) calls a JSON serializer available in the template (e.g., JsonOutput.toJson(property.res)) so the output is valid JSON; change the expression in the template step accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@distribution/tutorials/orchestration/50-Loop-get-Details.yaml`:
- Around line 32-38: The issue is that property.res may stay null when the
upstream $.products array is empty because the groovy block only initializes it
inside the loop; pre-initialize property.res to an empty list before the for
loop (e.g., add a groovy step that sets property.res = property.res ?: []) so
the output becomes [] instead of null, and then simplify the existing groovy
loop body to just property.res.add(...) (remove the conditional initialization
there). Ensure the pre-init step runs unconditionally prior to the for step that
iterates over $.products and that the loop continues to use
fn.jsonPath('$.price') as before.
- Around line 40-46: The template is inserting property.res with Groovy's
StreamingTemplateEngine which calls toString() and produces invalid JSON; update
the template content where "<%= property.res %>" is used so the expression
either (a) maps/collects property.res into JSON-serializable maps/values (use
property.res.collect to build plain maps with string keys for each product) or
(b) calls a JSON serializer available in the template (e.g.,
JsonOutput.toJson(property.res)) so the output is valid JSON; change the
expression in the template step accordingly.
|
/ok-to-test |
|
This pull request needs "/ok-to-test" from an authorized committer. |
… property.res %>` for better consistency.
Summary by CodeRabbit