Why do I get an IndexOutOfBoundsException when my else should prevent it?

235 views Asked by At

I am working on some sort of quiz and have a list of questions and answers, that get transferred to my view class via the controller. People can ask and answer questions on a page, my system then goes and "collects" those to make a quiz out of them.

If you are the first person to start the program / quiz, the question-list is empty. Therefore I want to check for an empty quiz with an if / else clause, the if-case seems to work fine, but the else-case throws an IndexOutOfBoundsException and I dont understand why. I would think that the else-part will not be used when the question-list is empty, therefore the exception should not be thrown. Should....

View class:

@(questionList: List[Question], answerList: List[Answer], answerRadioForm: Form[Answer])

@if(questionList.length == 0){
    No questions yet!
}

else {
<!-- As only the highest ranked question gets put into the List, there is only one entry on first place -->
<b>@questionList.get(0).questionText</b>

    @for(question <- questionList)  {
        @question.questionText - @question.ownerID <br>
    }
} 

Error:

[IndexOutOfBoundsException: Index: 0, Size: 0]
49          <b>"""),_display_(/*27.8*/questionList/*27.20*/.get(0).questionText),format.raw/*27.40*/("""</b>

So, what am I missing here?

2

There are 2 answers

1
hamena314 On BEST ANSWER

I have found a solution and altough it's bad practice to answer your own question, I have searched for several hours for this and maybe my answer helps somebody else:

There must not be a return / newline between the if / else.

Does NOT work:

@if(questionList.length == 0){
    No questions yet!
}

else { ...

Works:

@if(questionList.length == 0){
    No questions yet!
} else {

EDIT: As @if(questionList.length > 0){ does work also, is stable against accidentically inserting newlines and is a bit easier to read and understand, I will use this instead of the else.

3
Adi On

First, does your code compile, as there is no get method on List. You can use list.headOption instead.

Well, I could use questionList(0)

Another solution.

@questionList.headOption.map(q => <b>{q.text}</b>).getOrElse("No questions yet!")
@for(question <- questionList)  {
    @question.text - @question.ownerId <br>
}