1

I've got a function in which I'd like to return a seq of elements like this:

def getProcessPrerequisites(processTemplateId: Int): Seq[ProcessTemplatesModel] = { var processTemplates: Seq[ProcessTemplatesModel] = Seq() //Other function calls... processTemplateIds.foreach(processTemplateId => processTemplateDTO.getProcessTemplate(processTemplateId).map { case Some(processTemplate) => processTemplates = processTemplates :+ processTemplate println("List in foreach: " + processTemplates) case None => println("Process template not found: " + processTemplateId) case _ => println("Something went wrong processTemplateDTO.getProcessTemplate(" + processTemplateId + ")!") }) println("List in the end: " + processTemplates) processTemplates } 

Eventually, I iterate over a list of processTemplateIds in order to get the corresponding elements. However, scala decides, probably due to its asynchronous nature, to return an empty list in the end. The println within the foreach:

println("List in foreach: " + processTemplates) 

reveals that the list is not empty and is properly filled. Problem is, that it happens after this println:

println("List in the end: " + processTemplates) 

which is empty. How can I assure that the list is not empty or waits for the list to be filled? Am I doing something wrong? Thanks!

UPDATE

var test = "" processPrerequisitesDTO.getProcessPrerequisites(processTemplateId).map { processPrerequisiteIds => { test += " hello " processPrerequisiteIds.foreach(processTemplateId => processTemplateDTO.getProcessTemplate(processTemplateId).map { case Some(processTemplate) => processTemplates += processTemplate test += " hi " }) println("FirstPrint: " + test) } } println("SecondPrint: " + test) 

The "FirstPrint" says "ha" the "SecondPrint" is empty. Does this have to do with scoping? I don't get it, not even the " hi " is added...

1 Answer 1

3

Seq in Scala is immutable. Every time you do processTemplates :+ processTemplate the new Seq is created and original var processTemplates doesn't change. You can either

1) use map/fold instead of foreach and create required result without side effects

2) use mutable.Seq collection for val processTemplates and modify it, which is not recommended in scala because of side effects.

Sign up to request clarification or add additional context in comments.

8 Comments

How can I change the "old" processTemplates or lets say append an element to it? Because the list within the foreach contains more than one element. So apparently an element is added.
e.g. you can use += to append to mutable collection. More mutable collection: here
then I got the following error: found : models.ProcessTemplatesModel required: String
Hard to tell w/o looking at code. Check if the collection parameterized with ProcessTemplatesModel and the new elements are of the same type as well.
I've changed my declaration to: var processTemplates = scala.collection.mutable.ListBuffer.empty[ProcessTemplatesModel] now it works for adding the processTemplates like it already did before. However, the problem that it runs the println in the end first, still remains. I didn't win anything. I don't think it has something to do with the way I append an element to a list, rather than the asychronous behaviour. Every println at the end of the function is run before the adding even happens.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.