Hello Everyone,
I’m building a survey in Survey123 Connect with dynamic choice lists using the search() appearance.
Example expression: search("RCWParticipantsTable?url=https://services.arcgis.com/...../FeatureServer/0&orderByFields=ParticipantID",'matches','PropertyKey',${PropertyKey})
The expression works as expected to populate the list. However, when the survey first loads, the question displays all records from the feature layer before it gets filtered by the previous selection.
I tried using the relevant column to control this, but that approach still causes performance issues and completely hides the question (whereas I want it to remain visible).
In my case, I have six select_multiple questions that all use the same dynamic list (via the search() appearance) to choose a person from a pool of 2,220 participants. Loading the entire list six times has a significant performance impact.
Does anyone have a suggestion for keeping the dynamic choice list visible, but preventing it from showing all records until it’s filtered by another question?
Thanks in advance for any guidance!
JB
UPDATE Note:
I’d like to highlight that after publishing the survey, the issue occurs in both the mobile and desktop versions of the app. However, the survey works as expected ( list is not pre-loaded) in the web application.
Solved! Go to Solution.
@JoseBarrios1 I forgot, there is some different syntax for web vs field app unfortunately and I don't know why.
web: concat("COUNTRY?url=https://services.arcgis.com/P3ePLMYs2RVChkJx/arcgis/rest/services/World_Countries/FeatureServer/0?orderByFields=FID DESC")
field app/connect: concat("COUNTRY?url=https://services.arcgis.com/P3ePLMYs2RVChkJx/arcgis/rest/services/World_Countries/FeatureServer/0/&orderByFields=FID DESC")
It really makes it difficult because to use this you have to chose 1 type of form.
What would happen if you calculated your url parameters in a separate helper question, and made that question relevant on another question. That would mean there is no url until it becomes relevant.
url1: calculation: concat ("RCWParticipantsTable?url=https://services.arcgis.com/...../FeatureServer/0&orderByFields=ParticipantID",'matches','PropertyKey',",${PropertyKey}) relevant: string-length(${PropertyKey}) > 0
your search appearance in your visible question would be something like this: autocomplete search(${url1})
but the question ${url1} wouldn't be relevant until other conditions met. So the list should be blank until ${PropertyKey) is filled in and that url is calculated
Interesting challenge! When you say "all records from the feature layer", does that mean all attributes for each record of the unfiltered query? If so, you might have some performance gains if you make use of the optional (`filterColumn', `filterText') parameters of the search appearance; though I don't think this would necessarily stop the initial search going out.
If you're already filtering down to the column you care about to populate your dynamic choice lists, then I would recommend trying to break up the search query itself into using some parameters that are given by the user in their session. From the example you gave above, this could be done like so:
text | ParticipantID | What is your participant ID?
select_one dynamic_choice list | firstSearch | What are you searching for? | appearance = search("RCWParticipantsTable?url=concat("https://services.arcgis.com/...../FeatureServer/0&orderByFields=",${ParticipantID}),'matches','PropertyKey',${PropertyKey})
Total guess there if that will work, but assuming you can do that with the search appearance, I think the survey form would not be able to make any queries until it has all the values it needs from the user.
A wilder suggestion, which I am definitely not sure is possible, would be to try and pull the data (which you are currently getting in the search appearance) for the choice list as a JSON object into the survey using pulldata("@javascript" or "@json") and then making specific pulldata("@json") calculations to build your choice lists. If that is possible, it would certainly boost performance in your survey since you would only have to query the URL once and could continually use that same response as many times as you wanted in the survey.
there might be a few hacks. You could have a MaxRecordCount (always return max 10 for example) query parameter added to the service URL, or set it to 1 until a previous question is answered, then alter the variable size.
You could also have your search/filter parameter preset in the same way to some default value, which then updates dependent on that previous question being answered.
Hello Everyone,
Thank you all for your suggestions and support. Unfortunately, I still haven’t been able to find a solution to the issue. Let me try to explain the problem I’m encountering in more detail, particularly as it relates to how choice lists are rendered and filtered in Survey123. Let me try to explain the problem I’m encountering in more detail, particularly as it relates to how choice lists are rendered and filtered in Survey123.
Survey123 Performance Issue: Survey123 is loading full datasets into choice lists before applying any filters based on previous questions. This result in long loading times and significant performance degradation.
Here are some example of the workflow: On Page 01- Site selection
Expected Behavior:
The {ProjectName_ID} field should:
Current Behavior:
Another example on Page 2 - Participant Activity Section
A participant can have multiple roles.
Expected Behavior:
Current Behavior:
Current Workflow Setup
What I’ve Tried
Summary of the Core Problem
Survey123 is rendering full lists before applying filters based on previous answers.
This leads to unnecessary data being loaded, unfiltered lists being shown to users, and severe performance issues — especially when using search() appearance within repeats or dynamic-grid layouts
Hello Neal,
Thank you so much for taking the time to look further into this. I'm currently trying to implement your suggestion, but I'm having some difficulty adapting your code to fit my URL query. Would you mind taking a look at what I have so far?
Specifically, I need to use orderByFields=ParticipantID so that the "Add Participant" option appears last in the list. I’m also using matches instead of where, as I couldn’t get where to work correctly in my case.
Here is the current search() appearance expression I’m using:
autocomplete search("RCWParticipantsTable?url=https://services.arcgis.com/...../arcgis/rest/services/..../FeatureServer/0&orderByFields=Participan...",'matches','PropertyKey',${PropertyKey})
Any guidance you can provide would be greatly appreciated!
Thanks,
JB
Not an expert in this but the "where" clause I am using is part of the url parameters, where as the "matches" is part of the search parameters. The filter text maybe another options. I suggest making a test form and playing around with the various methods to get one search to function as you expect, then add in the concat and relevancy I explained above. Once you get one example to work, then copy that format to your full survey.
for yours to fit in to my example, it could be something like this
url1: concat("RCWParticipantsTable?url=<url> ,'matches','PropertyKey',", ${PropertyKey})
edit: couldn't get this to work with concat and matches, but the where clause should still work.
This is what you want to end up with:
autocomplete search("RCWParticipantsTable?url=https://services.arcgis.com/...../arcgis/rest/services/..../FeatureServer/0&orderByFields=Participan...&where=PropertyKey=${PropertyKey}")
but to get that to work and be dynamic you need to split out and calculate that where clause so:
concat("RCWParticipantsTable?url=https://services.arcgis.com/...../arcgis/rest/services/..../FeatureServer/0&orderByFields=Participan...&where=",${whcl})
whcl = concat('PropertyKey =',${PropertyKey})
Yes I'm having a long think about how to dynamically update the record count value after, subject to the relevant/previous question being completed.
It's surprising the filter value isn't then returning 0 records when blank.
Could you set a default value for the previous question such as "No Response" or a special character etc. that might then-kick in the filters.
Setting a fixed &resultRecordCount=300 for the moment might offer you some performance boost until a solution is found (I understand you've said it's not feasible as a real solution - which I agree with)
Note for posterity it is resultRecordCount, not maxRecordCount as I previously put.
Last one would be check you have the latest version of connect / republish a new test survey from the XLS etc.
@DavidPike I haven't tested but I would think a if statement would work for this case
if (${PropertyKey}="",concat("<url>","&resultRecordCount=300"), concat("RCWParticipantsTable?url=<url>&where=",${whcl}))