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)
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.
@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...