I started to look into questionnaires more. I noti...
# dev
b
I started to look into questionnaires more. I noticed in the Bot example for patient registration demo that values are referenced based on their position inside of the
items
array. Is there a way to retrieve the values in constant time? I would assume that attempting to parse information for a patient resource would be difficult by array index in the case you change questionnaire. I.e. adding given or legal names into the questionnaire which would cause all of the indexes to change. I know I can probably do an O(n) find based on the item's
linkId
but was seeing if there was a built-in alternative. It would also just be simpler to associate a name to like
items.givenName.answer[0].valueString
EDIT: This might answer my question. https://github.com/medplum/medplum-demo-bots/blob/main/src/patient-intake.ts
Copy code
const items = resource.item;

const [patientOutcome, patient] = await repo.createResource({
  resourceType: 'Patient',
  name: [
    {
      given: [items[0].answer[0].valueString],
      family: items[1].answer[0].valueString,
    },
  ],
  telecom: [
    {
      system: 'email',
      value: items[2].answer[0].valueString,
    },
    {
      system: 'phone',
      value: items[3].answer[0].valueString,
    }
  ]
});
assertOk(patientOutcome, patient);
console.log('Created patient', patient.id);

const [serviceRequestOutcome, serviceRequest] = await repo.createResource({
  resourceType: 'ServiceRequest',
  status: 'active',
  subject: createReference(patient),
  requester: resource.meta.author,
  reasonCode: [
    {
      text: items[4].answer[0].valueString,
    }
  ]
});
Here is the potential helper that will map it:
Copy code
/**
 * Returns all questionnaire answers as a map by link ID.
 * @param response The questionnaire response resource.
 * @returns Questionnaire answers mapped by link ID.
 */
export function getQuestionnaireAnswers(
  response: QuestionnaireResponse
): Record<string, QuestionnaireResponseItemAnswer> {
  const result: Record<string, QuestionnaireResponseItemAnswer> = {};
  buildQuestionnaireAnswerItems(response.item, result);
  return result;
}

/**
 * Recursively builds the questionnaire answer items map.
 * @param items The current questionnaire response items.
 * @param result The cumulative result map.
 */
function buildQuestionnaireAnswerItems(
  items: QuestionnaireResponseItem[] | undefined,
  result: Record<string, QuestionnaireResponseItemAnswer>
): void {
  if (items) {
    for (const item of items) {
      if (item.linkId && item.answer && item.answer.length > 0) {
        result[item.linkId] = item.answer[0];
      }
      buildQuestionnaireAnswerItems(item.item, result);
    }
  }
}
r
Hi @brandonin ! Yep that's a helper function we created to make it easier to work with questionnaire responses: https://www.medplum.com/docs/sdk/modules#getquestionnaireanswers
LinkId is the canonical "name" of the question, and this helper indexes the items by linkId, and handles nesting
166 Views