BB10 Cascades: ComponentDefinition, Switches and if-else if statements
I just spent the morning troubleshooting a particularly annoying issue in a Cascades application I'm writing. Seems like there are times when QML execution will just 'stop' with no error message logged anywhere I can see. The behavior can be reproduced if you have a ComponentDefinition in an attachedObjects block that you try to instantiate inside a switch statement.
Read on for details.
Background
I've had a love-hate relationship with the Cascades DropDown control since SDK Beta 3. At one point I wrote a custom control to extend it to be useful from QML. An Engineer from RIM contacted me and helped me better utilize the DropDown by creating an Option{} ComponentDefinition in my attachedObjects block (See the linked article for details). This allowed me to dynamically build out DropDown Options using QML.
Problem
Fast forward to today: I'm using the same technique to fill another DropDown control, the only difference being that I have a switch statement which fills the DropDown with different Options based on user input. This time it is not working and when I check slog2info via SSH session I don't see any error/warning/informational messages to help me figure out why QML/JS execution halts on the line that instantiates an Option.
Solution
After hours of troubleshooting permutations I was able to identify the root cause of the problem: the switch statement itself! When I replaced the switch for an if - else if - else block, the problem I was seeing went away.
This code works as it is not a switch statement:
// Option Changed handler inside a QML DropDown control
onSelectedOptionChanged: {
if(selectedOption.value === 1){
var opt = option.createObject();
opt.text = "Path 1";
opt.value = 1;
depositDropDown.add(opt);
} else if(selectedOption.value === 10){
var opt = option.createObject();
opt.text = "Path 2";
opt.value = 2;
depositDropDown.add(opt);
} else if(selectedOption.value === 20){
for(var i = 1; i <= 28; i++){ // Fill a DropDown with a list of Numbers
var opt = option.createObject();
opt.text = i.toString();
opt.value = i;
depositWhenDropDown.add(opt);
}
}
} // end onSelectedOptionChanged handler
Where this code does not work even though it should be functionally identical to the above if- else if code:
// Option Changed handler inside a QML DropDown control
onSelectedOptionChanged: {
switch(selectedOption.value){
case 1:
var opt = option.createObject();
opt.text = "Path 1";
opt.value = 1;
depositDropDown.add(opt);
break;
case 10:
var opt = option.createObject();
opt.text = "Path 2";
opt.value = 2;
depositDropDown.add(opt);
break;
case 20:
for(var i = 1; i <= 28; i++){ // Fill a DropDown with a list of Numbers
var opt = option.createObject();
opt.text = i.toString();
opt.value = i;
depositWhenDropDown.add(opt);
}
break;
} // End Switch Statement
} // end onSelectedOptionChangedHandler
Note
The above code examples rely on an attachedObjects block like this being available in QML:
//
// Per bug BBTEN-302: I need to specify a new ComponentDefinition in the attachedObjects section
// In order to add options to a DropDown
// https://7thzero.com/blog/blackberry-10-cascades-create-a-custom-control-dropdownlist/
//
attachedObjects: [
ComponentDefinition {
id: option
Option{}
}
]