Closed mrjones-plip closed 1 month ago
cc @latin-panda
I was not able to reproduce this behavior in a simple form:
type | name | label::en | hint | appearance | default | calculation |
---|---|---|---|---|---|---|
begin_group | qr_code | Capturing data from a QR code | field-list | |||
begin_group | qr_code_app | NO_LABEL | android-app-launcher | |||
string | action | NO_LABEL | hidden | com.google.zxing.client.android.SCAN | ||
begin_group | qr_code_app_outputs | NO_LABEL | android-app-outputs | |||
string | SCAN_RESULT | NO_LABEL | hidden | |||
end_group | qr_code_app_outputs | |||||
end_group | qr_code_app | |||||
string | health_card_id | Health card ID | Health card ID should be a 12 digit number | number | ../qr_code_app/qr_code_app_outputs/SCAN_RESULT |
Screencast from 2024-08-16 09-20-17.webm
Also, it seems like there is a disconnect between your linked example form and screenshots that you posted. In the linked form, the "Health card ID" field is a calculate
which should not actually be displayed in the form.
Oh - interesting! Thanks for the testing and follow up @jkuester . I've updated the form to be current with screenshots - sorry!
As well - I'll try and grab ya for a chat and report back our findings here.
Ah - I see a difference in your testing:
your steps are:
1234567890
0987654321
The bug we found is that in step 3 we re-scan the barcode in step 1. You're scanning a different barcode which we agree works (and is an odd work around)
Okay, after digging into this more, @mrjones-plip and I were able to reproduce the behavior with the simple form I described above (by re-scanning the same barcode). We found the issue is that the health_card_id
field gets the value from SCAN_RESULT
, but this value update is only triggered if the value stored in SCAN_RESULT
changes. So, if I open the form and scan the value 1234
, this value gets set for SCAN_RESULT
and the xform logic will update any expressions that depend on SCAN_RESULT
to reflect this value. This means that health_card_id
will get set to 1234
. However if the user goes and manually edits health_card_id
to be ""
(or anything else), the value for health_card_id
will change, but not the value for SCAN_RESULT
. SCAN_RESULT
will still be 1234
. Then, when the user re-scans the barcode with the value 1234
, the xform's logic knows that the value for SCAN_RESULT
did not change, and so it does not trigger an update to any of the dependent expressions. This is why health_card_id
does not get updated back to 1234
.
The most simple and clean way to avoid this problem is to update the form so that the SCAN_RESULT
field is the one shown to the user for editing. Then, the heath_card_id
can be a calculate
to save the value wherever it actually needs to be in the data hierarchy. This keeps the update flow of the data linear and avoids any kind of circular dependencies between the SCAN_RESULT
and health_card_id
fields.
type | name | label::en | hint | appearance | readonly | default | calculation |
---|---|---|---|---|---|---|---|
begin_group | qr_code | Capturing data from a QR code | field-list | ||||
begin_group | qr_code_app | NO_LABEL | android-app-launcher | ||||
string | action | NO_LABEL | hidden | com.google.zxing.client.android.SCAN | |||
begin_group | qr_code_app_outputs | NO_LABEL | android-app-outputs | ||||
string | SCAN_RESULT | Health card ID | Health card ID should be a 12 digit number | number | |||
end_group | qr_code_app_outputs | ||||||
end_group | qr_code_app | ||||||
calculate | health_card_id | ../qr_code_app/qr_code_app_outputs/SCAN_RESULT | |||||
end_group | qr_code |
With this new form structure, the user is able to update/clear the health card id value and then re-scan the same QR code as before.
Screencast from 2024-08-16 10-02-46.webm
It is a best practice to keep the data update flow as simple and linear as possible. That being said, this is not always possible for extra complex cases. The ODK spec does support the concept of a trigger
column that I think could possibly be useful in cases similar to this. Unfortunately, we do not support trigger
yet in the CHT.
Describe the bug
To Reproduce
Expected behavior The cleared field in step 3 above gets re-input in step 4. What happens is nothing.
NB - you can scan a 2nd barcode and then scan the 1st barcode as a work around, oddly.
Environment
Additional context Forum discussion on same