Collect: choice filter using instance requires additional term to function

1. What is the issue? Please be detailed.
While trying to filter some choices to only those used in subsequent questions (eg I have a large list of states, but the subsequent choices only use a subset of those states, so I don't want the enumerator to have to select states until they hit one with an item in it.[†]) my initial choice filter functioned in Enketo as expected, but in Collect it only returned the first matching choice.

Adding a filter term to the filter lookup then caused it to work in Collect, but it shouldn't be necessary?

Works in Enketo, returns one value in Collect (first)

Filter a question eg "Select state" to only those states present in the state column of the submissions choice list:
contains(join(' ',instance('submissions')/root/item/state),name)

Works in Collect & Enketo.

contains(join(' ',instance('submissions')/root/item[country=${country}]/state),name)

Even a 'dummy' filter in the instance lookup will cause it to work in Collect, eg

contains(join(' ',instance('submissions')/root/item[name!='']/state),name)

Footnote

[†] this is kind of a reverse choice filter. As the subsequent list gets bigger, the join becomes massive, so it can be incredibly slow to respond in Enketo, and eventually slow in Collect.

Also, if one of the options is a substring of another of the options but is not present in the subsequent list, that one will show anyway (and then show zero subsequent options), eg 'Virginia' would show up if 'West Virginia' was in the subsequent list. Is there an equivalent of selected-at to accomplish this kind of filter, or a more performant approach overall?

1 Like