android-fhir icon indicating copy to clipboard operation
android-fhir copied to clipboard

Re-selecting an option in a drop down item with valueString answer options is causing app to crash

Open KhumboLihonga opened this issue 1 year ago • 3 comments

Describe the bug An item with the type 'choice', using the drop down extension, and answer options comprised of valueStrings crashes the app when an option is re-selected. The first time the option is selected, nothing happens but when you attempt to select an other option from the same drop down, the app crashes.

Component Demo app

To Reproduce Steps to reproduce the behavior:

  1. Update the file 'new-patient-registration-paginated.json' to use an item of the type 'choice' for the country attribute, remove the initial expression attribute (because of this issue), and add valueString answer options.
  2. Run the demo app
  3. Tap on a patient
  4. Tap on the edit button
  5. Select a country
  6. Select a different country
  7. The app will crash with the error: Caused by: java.lang.IllegalArgumentException: Mismatching question type CHOICE and answer type string for PR-address-country

Expected behavior I expect the second country to be selected

Screenshots N/A

Smartphone (please complete the following information):

  • Device: Samsung A12
  • Android version: 11
  • Build number: RP1A.200720.012.A127FXXU4AUK1
  • Version: 30

Additional context Support for the string type for a choice widget was added in this PR. The updated item would look like this:

{
              "extension": [
                {
                  "url": "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl",
                  "valueCodeableConcept": {
                    "coding": [
                      {
                        "system": "http://hl7.org/fhir/questionnaire-item-control",
                        "code": "drop-down",
                        "display": "Drop down"
                      }
                    ],
                    "text": "Drop down"
                  }
                }
              ],
              "linkId": "PR-address-country",
              "definition": "http://hl7.org/fhir/StructureDefinition/Patient#Patient.address.country",
              "type": "choice",
              "answerOption": [
                {
                  "valueString": "Kenya"
                },
                {
                  "valueString": "Malawi"
                },
                {
                  "valueString": "Zambia"
                }
              ],
              "required": true,
              "text": "Country",
              "_text": {
                "extension": [
                  {
                    "extension": [
                      {
                        "url": "lang",
                        "valueCode": "sw"
                      },
                      {
                        "url": "content",
                        "valueString": "Nchi"
                      }
                    ],
                    "url": "http://hl7.org/fhir/StructureDefinition/translation"
                  }
                ]
              }
            }
          ]
        }

Would you like to work on the issue? Maybe the author of the PR can look into resolving this

KhumboLihonga avatar Aug 06 '22 10:08 KhumboLihonga

@f-odhiambo Kindly take a look

Gental-Giant avatar Aug 11 '22 12:08 Gental-Giant

Can you add the log trace for this @KhumboLihonga? CC @Gental-Giant

f-odhiambo avatar Aug 11 '22 12:08 f-odhiambo

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.google.android.fhir.demo, PID: 28311 org.hl7.fhir.exceptions.FHIRException: Type mismatch: the type Coding was expected, but org.hl7.fhir.r4.model.StringType was encountered at org.hl7.fhir.r4.model.QuestionnaireResponse$QuestionnaireResponseItemAnswerComponent.getValueCoding(QuestionnaireResponse.java:855) at com.google.android.fhir.datacapture.views.QuestionnaireItemDropDownViewHolderFactory$getQuestionnaireItemViewHolderDelegate$1.bind(QuestionnaireItemDropDownViewHolderFactory.kt:58) at com.google.android.fhir.datacapture.views.QuestionnaireItemViewHolder.bind(QuestionnaireItemViewHolderFactory.kt:61) at com.google.android.fhir.datacapture.QuestionnaireItemAdapter.onBindViewHolder(QuestionnaireItemAdapter.kt:99) at com.google.android.fhir.datacapture.QuestionnaireItemAdapter.onBindViewHolder(QuestionnaireItemAdapter.kt:43) at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7065) at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7107) at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6012) at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6279) at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118) at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114) at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303) at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627) at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587) at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665) at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134) at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851) at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404) at android.view.View.layout(View.java:24475) at android.view.ViewGroup.layout(ViewGroup.java:7383) at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1873) at android.view.View.layout(View.java:24475) at android.view.ViewGroup.layout(ViewGroup.java:7383) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at android.view.View.layout(View.java:24475) at android.view.ViewGroup.layout(ViewGroup.java:7383) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at android.view.View.layout(View.java:24475) at android.view.ViewGroup.layout(ViewGroup.java:7383) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at android.view.View.layout(View.java:24475) at android.view.ViewGroup.layout(ViewGroup.java:7383) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at android.view.View.layout(View.java:24475) at android.view.ViewGroup.layout(ViewGroup.java:7383) at com.google.android.material.appbar.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:148) at com.google.android.material.appbar.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:43) at com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:2172) at androidx.coordinatorlayout.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:918) at android.view.View.layout(View.java:24475) at android.view.ViewGroup.layout(ViewGroup.java:7383) at androidx.drawerlayout.widget.DrawerLayout.onLayout(DrawerLayout.java:1263) at android.view.View.layout(View.java:24475) E/AndroidRuntime: at android.view.ViewGroup.layout(ViewGroup.java:7383) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at android.view.View.layout(View.java:24475) at android.view.ViewGroup.layout(ViewGroup.java:7383) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673) at android.widget.LinearLayout.onLayout(LinearLayout.java:1582) at android.view.View.layout(View.java:24475) at android.view.ViewGroup.layout(ViewGroup.java:7383) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at android.view.View.layout(View.java:24475) at android.view.ViewGroup.layout(ViewGroup.java:7383) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673) at android.widget.LinearLayout.onLayout(LinearLayout.java:1582) at android.view.View.layout(View.java:24475) at android.view.ViewGroup.layout(ViewGroup.java:7383) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at com.android.internal.policy.DecorView.onLayout(DecorView.java:1227) at android.view.View.layout(View.java:24475) at android.view.ViewGroup.layout(ViewGroup.java:7383) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:4260) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3695) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2618) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9971) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1010) at android.view.Choreographer.doCallbacks(Choreographer.java:809) at android.view.Choreographer.doFrame(Choreographer.java:744) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:995) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:246) at android.app.ActivityThread.main(ActivityThread.java:8653) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

KhumboLihonga avatar Aug 11 '22 12:08 KhumboLihonga

@KhumboLihonga seem like you using valueString for choice instead of valueCoding , can you confirm if this is accurate?

f-odhiambo avatar Aug 15 '22 08:08 f-odhiambo

Yes, that is correct. As per the FHIR spec, a valueString answerOption should be supported and this support was added in this PR.

When a valueString is used, the choice is rendered accordingly. When an option is selected, again everything works fine. But when you attempt to re-select the same option or a different option is when the crash is happening.

KhumboLihonga avatar Aug 17 '22 14:08 KhumboLihonga