LHNCBC / lforms

See the project website at http://lhncbc.github.io/lforms/, or view the demo website at https://lhcforms.nlm.nih.gov/lhcforms.
Other
107 stars 56 forks source link

mergeFHIRDataIntoLForms() mutating FHIR QuestionnaireResponse object #154

Open fongsean opened 1 month ago

fongsean commented 1 month ago

Hi,

I've been playing around with LHC-Forms to test compatibility with the CSIRO Renderer (and do debugging). It's set up to be like Brian's https://dev.fhirpath-lab.com/Questionnaire/tester.

I've noticed that the mergeFHIRDataIntoLForms() function mutates the FHIR QuestionnaireResponse passed into the function. This is how i'm using it:

const lhcQ = LForms.Util.convertFHIRQuestionnaireToLForms(questionnaire, 'R4');
const lhcQR = LForms.Util.mergeFHIRDataIntoLForms(
  'QuestionnaireResponse',
  deepCopyQR,
  lhcQ,
  'R4'
);
LForms.Util.addFormToPage(lhcQR, 'myFormContainer', {
  prepopulate: false
})

The issue I'm facing is - when I switch between the two renderers without explicitly updating the QR state, any non-first answers of repeating items are removed from the initial FHIR QuestionnaireResponse, which causes those answers to be removed in another renderer.

Attached are two videos performing the following steps:

  1. Fill in the Repeats Test (String) item with two answers and update QR view
  2. Navigate to on LHC Forms
  3. Navigate back to CSIRO without updating QR
  4. Second field of Repeats Test (String) disappeared
  5. Fill in the Repeats Test (String) item with two answers again and update QR view
  6. Navigate to on LHC Forms and update QR view
  7. Navigate back to CSIRO
  8. Second field of Repeats Test (String) is present
  9. Repeat steps 1-4 - fields disappeared again
  10. Remove LHC forms from source code
  11. Doesn't happen anymore

The first video uses the CSIRO renderer as the main renderer, while the second uses LHC-Forms. In the second video, it still happens even after the CSIRO renderer is removed.

This issue was first brought to me by @brianpos.

https://github.com/user-attachments/assets/24d59b08-d694-4972-aa78-2fe294cf0886

https://github.com/user-attachments/assets/6a6160ca-406d-4226-96ef-8c1df2c3c572

Potential fix:

Performing a deep clone of the FHIR QuestionnaireResponse before executing the function's logic should fix it.

Here's how I workaround it in my app:

const deepCopyFhirQR = cloneDeep(questionnaireResponse); // from lodash, could use structuredClone() as well
const lhcQ = LForms.Util.convertFHIRQuestionnaireToLForms(questionnaire, 'R4');
const lhcQR = LForms.Util.mergeFHIRDataIntoLForms(
  'QuestionnaireResponse',
  deepCopyFhirQR,
  lhcQ,
  'R4'
);
LForms.Util.addFormToPage(lhcQR, 'myFormContainer', {
  prepopulate: false
})

Open to any discussion on better/more efficient ways to address it.

fongsean commented 1 month ago

Happy to deploy the test app if it helps. Also, it's a React app.

lhcye commented 1 month ago

Hi Sean, thanks for reporting this. I didn't expect the QR would be modified. A deep clone should be used at least. In fact the Questionnaire resource is deep cloned when it is loaded to the LHC-Forms widget. I will have it fixed next week.