Enketo form load error with instance lookup in choice filter 'Cannot read properties of undefined (reading 'length')

Background;

  • Entity list has ~6000 items, each with a photo filename in the image field
  • Photos can't currently be shown under select labels from CSVs or Entity lists so the UUID/label/image/big-image are duplicated (by using the Entity OData URL to powerquery in these fields and spill into the choice list) from the Entity list as an internal choice list, to
    • force upload of media in Central
    • give a filtered select that shows images (Only in Collect, Enketo hates this one weird trick)
  • As the survey progresses I update an entity field (eg 'unsurveyed' to 'surveyed') and I don't want these items to appear after an upload and a sync, so I want to filter them out. I also don't want to have to update the definition with each upload.

At first, as Enketo doesn't like [*] a choice filter like this:
name=instance('entitylist')/root/item[${update_status}!='surveyed']/name

I tried the following, but it threw the same ‘Cannot read properties of undefined (reading ‘length’) error:
contains(join(' ',instance('entitylist')/root/item[${update_status}!='surveyed']/name),name)
So after screaming into the void for a while I searched the error and came back to this thread and figured, why not try calculating the join separately and then using it in the filter, and it worked! I think I spoke too soon:
calculate_field as join(' ',instance('entitylist')/root/item[${update_status}!='surveyed']/name)
choice filter as contains(${calculate_field},name)

Edit:

My join was breaking in Enketo, some didn't work, looks purely like the order of my expression=field vs field=expression in the instance prevented the join from working;

  • Not OK
    • join(' ',instance('entitylist')/root/item[substring-after(${update_subarea},'prefix_')=subarea and ${update_area}=area and survey_status!='Surveyed']/name)
  • OK
    • join(' ',instance('entitylist')/root/item[substring-after(${update_frame},'frame_')=frame and ${update_area}=area and survey_status!='Surveyed']/name)
    • join(' ',instance('entitylist')/root/item[substring-after(survey_status!='Surveyed']/name)
    • join(' ',instance('entitylist')/root/item[subarea=substring-after(${update_subarea},'prefix_') and ${update_area}=area and survey_status!='Surveyed']/name) :rage: :confetti_ball:

Based on that I tried skipping the separate join calc and recombining the working join with the contains as below, but of course Cannot read properties of undefined (reading 'length'):
contains(join(' ',instance('entitylist')/root/item[subarea=substring-after(${update_subarea},'prefix_') and ${update_area}=area and survey_status!='Surveyed']/name),name)

Edit 2:

I updated an entity from 'unsurveyed' to 'surveyed', it disappeared in Collect but not in Enketo. I swapped the survey_status around and got a whole new error in Enketo

Not sure how to handle: '{"stack":[{"t":"root","tokens":[{"t":"bool","v":false},{"t":"op","v":4},57005,{"t":"op","v":8}]}],"cur":{"v":"areaand"}}

So why not swap one more filter...
join(' ',instance('entitylist')/root/item[subarea=substring-after(${update_subarea},'prefix_') and area=${update_area} and 'Surveyed'!=survey_status]/name)

It works. In Collect and Enketo, correctly showing or hiding items with 'surveyed' status. That's all I can handle for today. :sleeping:


@Tyler_Depke re this thread, this might interest you, it validates the process of create an entity with a filename against it, query in the entity list and filenames to the form and use that as an internal choice list with images.

[*] I have lost most of today butting up against things Enketo doesn't like, including hours spent trying to understand what is unacceptable in a constraint expression but totally fine in a normal calculation/relevance, like using jr:choice-name, getting a true/false result from a count... :rage: