-
-
Notifications
You must be signed in to change notification settings - Fork 326
Description
Is your feature request related to a problem? Please describe.
The current External Android App Launcher functionality will serialize lists as JSON arrays when returning data back into the form model. Then, the cht-core webapp code will insert the data into repeats with the appropriate appearance.
This approach is really the only way to handle an array of objects since you need the repeat with child fields to model the properties on each object. However, it is a bit confusing when it comes to arrays of primitive values. In that case, there is no named property to put in the repeat to hold the array value. This is why we end up having the android-app-object-list vs the android-app-value-list...
Unfortunately, Enketo repeats are still pretty janky, particularly when you are using them in non-trivial ways. In practice we have found lots of challenges supporting complex workflows involving things like nested repeats, repeats whose relevance changes, etc. Anything we can do to avoid using repeats for complex operations in a form would be an improvement and I think we should be able to handle lists of primitive values without needing a repeat or android-app-value-list appearance.
Describe the solution you'd like
Enketo has great support for lists of primitive values (modeled as space-delimited strings). These "node sets" can be produced by normal select_multiple questions where the value for the field is actually just a space-delimited string with all the selected values. So, built-in functions like selected-at and count-selected can be used to parse any space-delimited string.
When de-serializing a JSON array of primitive values in the android-app-launcher widget, we could check if the associated form model field is a repeat with either the android-app-object-list or android-app-value-list. If so, we keep the existing behavior (so the changes remain passive). However, if the field is not a repeat, then we should de-serialize the JSON array as a space-delimited string stored directly in the named field. Then all the down-stream form logic can process the value as a node set and operate accordingly.
Describe alternatives you've considered
Support for this functionality was originally added in this cht-android branch. However, I think this would be a breaking change if we ship the changes there (since cht-android has a decide if it is going to return the field as a string or array without knowing if the field has the android-app-value-list appearance or not. By making this change in cht-core, it should be passive for forms that are already using android-app-value-list, but will allow the new functionality for forms without that appearance.
Additional context
See the forms here (https://github.com/medic/fake-health-pulse#using-fake-healthpulse-ai) for examples with and without repeats.