When we initially developed our open-source FhirBlaze application we ran into several problems when attempting to create a Patient. The Patient class is complex (FHIR Patient spec) and contains complex properties that do not lend themselves to easy integration with Blazor’s excellent EditForm component.
But let’s back up and see how a simplified Patient might be created.
Using a Simple Model
Let’s say we want our Patient to have:
- a first name
- a last name
- an ID
- a date of birth
Our SimplePatient model would look like this:
public class SimplePatient
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string PatientID { get; set; }
public DateTime Birthdate { get; set; }
}
Then it’s pretty easy to create an EditForm to model against this class:
<EditForm Model="Patient" OnValidSubmit="SavePatient" class="form-horizontal">
<DataAnnotationsValidator/>
<ValidationSummary />
<div class="form-group">
<label>ID</label>
<InputText required @bind-Value="Patient.PatientID" />
</div>
<div class="form-group">
<label>Birthday</label>
<InputDate required @bind-Value="Patient.Birthdate" />
</div>
<div class="form-group">
<label>First</label>
<InputText required @bind-Value="Patient.FirstName" />
</div>
<div class="form-group">
<label>Last</label>
<InputText required @bind-Value="Patient.LastName" />
</div>
@if (Processing)
{
<button type="button" class="btn btn-primary-outline" disabled >Processing</button>
}
else{
<button type="submit" class="btn btn-primary">Save</button>
}
</EditForm>
This then gives us a simple form and we can now create SimplePatients- but there’s a catch! We’re not creating FHIR objects! So we can’t store them in a FHIR capable system- and we can’t load Patients from a FHIR capable system into our app!
Complexity of FHIR Makes This Model Unscalable
At this point we have several options- we can create toFHIR() and fromFHIR() methods to our SimplePatient. But this is complex and as we import more properties from FHIR into our SimplePatient model- complexity will scale! Instead let’s use native HL7 FHIR objects
The Complexities of HL7 FHIR Objects
We’ll focus on Patient, but you’ll see examples of these problems on Practionier, Questionnaire, QuestionnaireResponse, and more! You should be able to apply the principles below.
List Containing Complex Objects (Patient.Identifier)
Look at Patient.Id. It’s a list of Identifier Objects. Each Identifier contains a string that represents the system for the Identifier (ex: “http://somelink.spac”) and a string representing the Value (ex: “123-123-123-123”).
Representing this in a form would look like this:
<EditForm model=@Patient>
@foreach (var id in FhirPatient.Identifier)
{
<div class="form-group">
<label>Patient ID </label>
<InputText required @bind-Value=@id.Value/>
</div>
}
</EditForm>
List Containing Lists (Patient.Name.Family)
Look at Patient.Name. It’s a list of HumanName objects. Each HumanName contains a single Family name (ex: “Brown”). Unlike the previous Identifier objects, each HumanName also contains a List of Given names (ex: “Dave”,”John”.
We can use the same syntax as above for creating Family names:
@foreach(var PatientName in FhirPatient.Name)
{
<div class="form-group">
<label>Family Name</label>
<InputText required @bind-Value=@PatientName.Family />
</div>
}
List Containing Arrays (Patient.Name.Given)
But for the Given name we can’t use a foreach because Given is an iEnumerable<string> and we can’t bind the contents of an iEnumerable. Luckily we CAN manipulate the more complex GivenElement. Each complex class will contain Elements that are exclusive to C#.
@foreach(var PatientName in FhirPatient.Name)
{
<div class="form-group">
@foreach (var gName in PatientName.GivenElement){
<label>Given Name</label>
<InputText required @bind-Value=@(((FhirString)gName).Value) />
}
</div>
<div class="form-group">
<label>Family Name</label>
<InputText required @bind-Value=@PatientName.Family />
</div>
}
Complete Example
You can see a complete example of the above in our FhirBlaze project. Happy FHIR coding!
Posted at https://sl.advdat.com/3neeZZf