# Looping for each char in string

**URL:** https://community.gatling.io/t/looping-for-each-char-in-string/6159
**Category:** Gatling (Open-Source)
**Created:** [June 22, 2021, 7:58am UTC](https://community.gatling.io/t/looping-for-each-char-in-string/6159 "2021-06-22T07:58:18Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![Terry\_PITZ](https://avatars.discourse-cdn.com/v4/letter/t/49beb7/32.png) [@Terry\_PITZ](https://community.gatling.io/u/Terry_PITZ)
#### Post date: [June 22, 2021, 7:58am UTC](https://community.gatling.io/t/looping-for-each-char-in-string/6159/1 "2021-06-22T07:58:18Z")

</div>

Hi,

I am trying to send a request for each char in a String (in order to test an autocomplete service), but no request is sent:

var tmp = “”  
val autocompleteMobile: ChainBuilder = exec(session =\> {  
session(“text”).as[String].foreach { c =\>  
tmp = tmp.concat(c.toString)  
println("Mot: " + tmp)  
exec(http(“Autocomplete MOBILE”)  
.get(“my\_url/autocomplete?text=${tmp}”)  
}  
session  
})

this ChainBuilder (autocompleteMobile) is called at a scenario level in another file like this:  
val mobileAutocomplete: ScenarioBuilder = scenario(“Mobile autocomplete”)  
.randomSwitch(  
20d → feed(cl1).feed(search\_word).exec(autocompleteMobile),  
20d → feed(cl2).feed(search\_word).exec(autocompleteMobile),  
20d → feed(cl3).feed(search\_word).exec(autocompleteMobile),  
20d → feed(cl4).feed(search\_word).exec(autocompleteMobile),  
20d → feed(cl5).feed(search\_word).exec(autocompleteMobile)  
)

When I execute this, I can see the expected behaviour but no request is sent:

**logs:**

Simulation simulations.Nominal started…  
Mot: p  
Mot: pa  
Mot: par  
Mot: parm  
Mot: parme  
Mot: parmes  
Mot: parmesa  
Mot: parmesan

[…] There were no requests sent during the simulation, reports won’t be generated

Any idea on what could have happenned?

Thank you in advance,

Terry

This e-mail and any attachment are confidential and intended solely for the use of the individual to whom it is addressed. If you are not the intended recipient, please telephone or email the sender and delete this message and any attachment from your system. Unauthorized publication, use, dissemination, forwarding, printing or copying of this e-mail and its associated attachments is strictly prohibited.

Let’s respect the environment together. Only print this message if necessary.

---

<div class="post-metadata">

### Author: ![slandelle](https://dub1.discourse-cdn.com/flex013/user_avatar/community.gatling.io/slandelle/32/4_2.png) [@slandelle](https://community.gatling.io/u/slandelle)
#### Post date: [June 22, 2021, 8:06am UTC](https://community.gatling.io/t/looping-for-each-char-in-string/6159/2 "2021-06-22T08:06:30Z")

</div>

That can’t work.

[https://gatling.io/docs/gatling/reference/current/general/scenario/#exec](https://gatling.io/docs/gatling/reference/current/general/scenario/#exec)

Gatling DSL components are immutable `ActionBuilder`(s) that have to be chained altogether and are only built once on startup. The result is a workflow chain of `Action`(s). These builders don’t do anything by themselves, they don’t trigger any side effect, they are just definitions. As a result, creating such DSL components at runtime in functions is completely meaningless. If you want conditional paths in your execution flow, use the proper DSL components (`doIf`, `randomSwitch`, etc)

You have to use a proper Gatling DSL loop, not a scala loop inside a function.

---

<div class="post-metadata">

### Author: ![Terry\_PITZ](https://avatars.discourse-cdn.com/v4/letter/t/49beb7/32.png) [@Terry\_PITZ](https://community.gatling.io/u/Terry_PITZ)
#### Post date: [June 22, 2021, 8:24am UTC](https://community.gatling.io/t/looping-for-each-char-in-string/6159/3 "2021-06-22T08:24:38Z")

</div>

Thank you Stéphane,

I try doing this in a Gatling’s foreach loop, but I can’t make it work because foreach expects scala.collection.immutable.Seq and I give him a String. I need to loop for each char. I am trying some other stuff.

@sujinsa, thank you too ! But this is not what I want to do.  
For a given word (let’s say “banana”), I want to iterate over each char, and send multiple requests sequentially:  
req1 with ‘b’  
req2 with ‘ba’  
req3 with ‘ban’  
etc…

---

<div class="post-metadata">

### Author: ![Terry\_PITZ](https://avatars.discourse-cdn.com/v4/letter/t/49beb7/32.png) [@Terry\_PITZ](https://community.gatling.io/u/Terry_PITZ)
#### Post date: [June 28, 2021, 7:43am UTC](https://community.gatling.io/t/looping-for-each-char-in-string/6159/4 "2021-06-28T07:43:25Z")

</div>

Hi,  
I try to find a solution but I still can’t find one.  
Is this possible ?

For now I simply try to print a session atrribute but this won’t work:

var tmp = “”  
var list: Seq[String] = SeqString

val autocompleteMobile: ChainBuilder = exec { session =\>  
session(“text”).as[String].foreach { c =\> //getting value from feeder  
tmp = tmp.concat(c.toString)  
list = list :+ tmp  
}  
println("out loop: " + list) // prints : “out loop: List(c, cr, cri, cris, crist, crista, cristal, cristali, cristalin, cristaline)”  
session.set(“liste”, list)

println(“Liste:” + session(“liste”).validate[Seq[String]]) // prints nothing =\> Liste:Failure(No attribute named ‘liste’ is defined)  
session  
}.exec(…)

Any idea why I cannot find the session attribute liste ?

Thank you in advance

---

<div class="post-metadata">

### Author: ![slandelle](https://dub1.discourse-cdn.com/flex013/user_avatar/community.gatling.io/slandelle/32/4_2.png) [@slandelle](https://community.gatling.io/u/slandelle)
#### Post date: [June 28, 2021, 7:47am UTC](https://community.gatling.io/t/looping-for-each-char-in-string/6159/5 "2021-06-28T07:47:27Z")

</div>

[https://gatling.io/docs/gatling/reference/current/session/session\_api/#setting-attributes](https://gatling.io/docs/gatling/reference/current/session/session_api/#setting-attributes)

`Session` instances are immutable!

---

<div class="post-metadata">

### Author: ![Terry\_PITZ](https://avatars.discourse-cdn.com/v4/letter/t/49beb7/32.png) [@Terry\_PITZ](https://community.gatling.io/u/Terry_PITZ)
#### Post date: [June 28, 2021, 8:02am UTC](https://community.gatling.io/t/looping-for-each-char-in-string/6159/6 "2021-06-28T08:02:58Z")

</div>

Sorry but I don’t understand why this does not work:

I try to do this:

var tmp = “”  
var list: Seq[String] = SeqString // var is for mutable variables

val autocompleteMobile: ChainBuilder = exec { session =\>  
session(“text”).as[String].foreach { c =\>  
tmp = tmp.concat(c.toString)  
list = list :+ tmp  
}  
val tmp\_list: Seq[String] = list // I create a tmp\_list with keyword ‘val’ which should be immutable  
println("out loop: " + list)  
session.set(“liste”, tmp\_list)

println(“Liste:” + session(“liste”).validate[Seq[String]])  
session  
}

This still does not work.  
Liste:Failure(No attribute named ‘liste’ is defined)

Immutable means the value does not have to change after declaration right ? I just do session.set and session.get for printing. Can you please enlighten me ?

---

<div class="post-metadata">

### Author: ![sbrevet](https://dub1.discourse-cdn.com/flex013/user_avatar/community.gatling.io/sbrevet/32/830_2.png) [@sbrevet](https://community.gatling.io/u/sbrevet)
#### Post date: [June 28, 2021, 8:27am UTC](https://community.gatling.io/t/looping-for-each-char-in-string/6159/7 "2021-06-28T08:27:17Z")

</div>

Hi!

Take care that `session#set` returns a new instance. (as `session` is immutable, a new instance is returned instead).

```auto
exec { session =>
  session("text").as[String].foreach { c =>
    tmp = tmp.concat(c.toString)
    list = list :+ tmp
  }
  val sessionWithList = session.set("liste", list) // <= new instance is created here!

  println("Liste:" + sessionWithList("liste").validate[Seq[String]]) // <= use your new session
  sessionWithList
}

```

Cheers!

---

<div class="post-metadata">

### Author: ![Terry\_PITZ](https://avatars.discourse-cdn.com/v4/letter/t/49beb7/32.png) [@Terry\_PITZ](https://community.gatling.io/u/Terry_PITZ)
#### Post date: [June 28, 2021, 8:33am UTC](https://community.gatling.io/t/looping-for-each-char-in-string/6159/8 "2021-06-28T08:33:50Z")

</div>

That was it ! Thank you very much !

---

<div class="post-metadata">

### Author: ![Terry\_PITZ](https://avatars.discourse-cdn.com/v4/letter/t/49beb7/32.png) [@Terry\_PITZ](https://community.gatling.io/u/Terry_PITZ)
#### Post date: [June 28, 2021, 9:37am UTC](https://community.gatling.io/t/looping-for-each-char-in-string/6159/9 "2021-06-28T09:37:01Z")

</div>

Hi Again,

Sorry for being unable to continue on my own, but I still cannot understand why it does not work. My need is to be able to iterate over a String, and send an HTTP request for each char in order to inject load to an autocomplete service:

var tmp = “”  
var list: Seq[String] = SeqString

val autocompleteMobile: ChainBuilder = exec { session =\>  
session(“text”).as[String].foreach { c =\>  
tmp = tmp.concat(c.toString)  
list = list :+ tmp  
}  
val newSession = session.set(“liste”, list)  
println(“Liste:” + newSession(“liste”).as[Seq[String]]) // This works now =\> prints “Liste:List(l, la, lai, lait)”

newSession

}.exec( session =\> { //Here is the part where I cannot iterate over the List

println("List before foreach: " + session(“liste”).as[Seq[String]]) // Works fine too, prints “List before foreach: List(l, la, lai, lait)”  
foreach(session(“liste”).as[Seq[String]], “text”) { // At this point, this does not work. =\> logs show “There were no requests sent during the simulation, reports won’t be generated”, which is normal. But nothing is printed before.  
exec { session =\>  
println(“Element: ${text}”) // I’m expecting this code to print each element of my List, but nothing is done. It’s like foreach does not iterate over it.  
//future http call will be here  
session  
}  
}  
session  
}

From the documentation: _sequenceName_ can be a sequence, an EL string pointing to a Seq[Any] Session attribute, or an Expression[Seq[Any]]

It seams that my session attribute is one of this.  
Any help would be appreciated, thank you in advance.

Terry

---

<div class="post-metadata">

### Author: ![Terry\_PITZ](https://avatars.discourse-cdn.com/v4/letter/t/49beb7/32.png) [@Terry\_PITZ](https://community.gatling.io/u/Terry_PITZ)
#### Post date: [June 29, 2021, 2:17pm UTC](https://community.gatling.io/t/looping-for-each-char-in-string/6159/10 "2021-06-29T14:17:57Z")

</div>

Finally, I got it worked !

I post the solution here for those who will need it later on.

var tmp = “”  
var list: Seq[String] = SeqString

val autocompleteMobile: ChainBuilder = exec { session =\>  
session(“text”).as[String].foreach { c =\>  
tmp = tmp.concat(c.toString)  
list = list :+ tmp  
}  
val newSession = session.set(“liste”, list)  
newSession  
}.exec(  
foreach("${liste}", “text”) {  
exec(http(“Autocomplete MOBILE”)  
.get("/my\_uri/${text}")  
.header(“id”, “${catalog}”))  
}  
)

For exemple, with text=bed, this will send 3 requests:

1. /my\_uri/b
2. /my\_uri/be
3. /my\_uri/bed

---

<div class="post-metadata">

### Author: ![slandelle](https://dub1.discourse-cdn.com/flex013/user_avatar/community.gatling.io/slandelle/32/4_2.png) [@slandelle](https://community.gatling.io/u/slandelle)
#### Post date: [June 29, 2021, 2:22pm UTC](https://community.gatling.io/t/looping-for-each-char-in-string/6159/11 "2021-06-29T14:22:24Z")

</div>

This is wrong.

You’ve defined tmp and list accumulators as global, hence shared amongst all virtual users.  
This is going to break as soon as you’ll run more than 1 concurrent user.

Those accumulators should be unique per virtual user, hence stored inside their respective Session.

---

<div class="post-metadata">

### Author: ![Terry\_PITZ](https://avatars.discourse-cdn.com/v4/letter/t/49beb7/32.png) [@Terry\_PITZ](https://community.gatling.io/u/Terry_PITZ)
#### Post date: [July 8, 2021, 10:12am UTC](https://community.gatling.io/t/looping-for-each-char-in-string/6159/12 "2021-07-08T10:12:19Z")

</div>

Hi,

I think this might be a solution.  
This works and the variables are saved as session attributes.

val autocompleteMobile: ChainBuilder = exec { session =\>  
var tmpSession = session.set(“tmp”, “”).set(“list”, new ListBufferString)

session(“text”).as[String].foreach { c =\>  
tmpSession = tmpSession.set(“tmp”, tmpSession(“tmp”).as[String].concat(c.toString))  
tmpSession = tmpSession.set(“list”, tmpSession(“list”).as[ListBuffer[String]] += tmpSession(“tmp”).as[String])  
}

val newSession = tmpSession.set(“liste”, tmpSession(“list”).as[ListBuffer[String]].toList)  
newSession  
}.exec(  
foreach("${liste}", “text”) {  
exec(http(“Autocomplete MOBILE”)  
.get("/my\_uri/${text}")  
.header(“id”, “${catalog}”))  
}  
)

NOTE:  
I tried to replace these lines:  
tmpSession = tmpSession.set(“tmp”, tmpSession(“tmp”).as[String].concat(c.toString))  
tmpSession = tmpSession.set(“list”, tmpSession(“list”).as[ListBuffer[String]] += tmpSession(“tmp”).as[String])

with:  
tmpSession = tmpSession.set(“tmp”, tmpSession(“tmp”).as[String].concat(c.toString)).set(“list”, tmpSession(“list”).as[ListBuffer[String]] += tmpSession(“tmp”).as[String])

But this does not work because tmpSession(“tmp”).as[String] has no value in the first loop.

Terry

---

<div class="post-metadata">

### Author: ![vu.nguyen](https://avatars.discourse-cdn.com/v4/letter/v/ba9def/32.png) [@vu.nguyen](https://community.gatling.io/u/vu.nguyen)
#### Post date: [July 8, 2021, 7:56pm UTC](https://community.gatling.io/t/looping-for-each-char-in-string/6159/13 "2021-07-08T19:56:21Z")

</div>

Terry - see if this alternative works for you

val autocompleteMobile: ChainBuilder =  
repeat(session =\> session(“text”).as[String].length, idx) {  
exec(session =\>  
session  
.set(“input”, session(“text”).as[String].take(idx + 1))  
)  
.exec(  
http(“Autocomplete MOBILE”)  
.get("/my\_uri/${input}")  
.header(“id”, “${catalog}”)  
)  
}
