Reputation: 147
I am not sure if it is even possible, but I wish to add a closure with a loop in a multiline string that would generate another multiline string at each loop.
String body = """\
Total Invoice Amount: £${totalInvAmt}
${quantities.each { qty ->
Offer offer = Offer.findByShoppingItem(qty.shoppingItem)
def itemDetails = """\
Name: ${offer.itemName}
Qty: $qty.value"""
itemDetails
}}
"""
The closure will loop over a list of items and for each item concatenate an multistring. All this produces is
Total Invoice Amount: £1100
[100, 100]
Thanks in advance for any help
Upvotes: 2
Views: 2065
Reputation: 27220
You could use a template engine.
import groovy.text.GStringTemplateEngine
def music = [:]
music.Riverside = ['Second Life Syndrome', 'Anno Domini High Definition']
music.Beardfish = ['Destined Solitare', 'Mammoth']
def templateText = '''
Number Of Artists: ${music.size()}.
<% music.each { artist, albums -> %>\
Artist Name: ${artist}
<% albums.each { albumTitle -> %>\
Album Title: ${albumTitle}
<% } %>
<% } %>
'''
def engine = new GStringTemplateEngine()
def template = engine.createTemplate(templateText).make(music:music)
println template.toString()
That will produce output like this:
Number Of Artists: 2.
Artist Name: Riverside
Album Title: Second Life Syndrome
Album Title: Anno Domini High Definition
Artist Name: Beardfish
Album Title: Destined Solitare
Album Title: Mammoth
You have a number of options and a good bit of flexibility in how you put that together. See http://beta.groovy-lang.org/templating.html for more info.
I hope that helps.
Upvotes: 0
Reputation: 160191
Here's pseudo-code that does something closer to what you want, delta I'm not going to try to reproduce your data structs etc. without an SSCCE.
Nutshell: each
iterates, you want to collect
.
body = """
Total Invoice Amount: £${totalInvAmt}
${quantities.collect { qty ->
offer = Offer.findByShoppingItem(qty.shoppingItem)
"""
Name: ${offer.itemName}
Qty: ${qty.value}
"""
}.join('\n')}
"""
I'd urge you never to do anything like this; it's abusive. At a minimum the inner string generation should be handled in its own method, not wedged in the middle of another string. It's difficult to read and maintain.
Upvotes: 1