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{}
     }
]