I'm trying to create Dart classes for FHIR resources defined in Json. The full Json schema for FHIR is here if anyone wants to look. My issue is with a oneOf declaration. Specifically, I have a class like the following (I'm not including the full class definition here, although I can if anyone thinks it would be helpful):
class Bundle_Entry {
Resource resource;
Bundle_Entry(this.resource});
factory Bundle_Entry.fromJson(Map<String, dynamic> json) => _$Bundle_EntryFromJson(json);
Map<String, dynamic> toJson() => _$Bundle_EntryToJson(this);
}
My problem is that ResourceList is defined as oneOf a number of other classes.
"ResourceList": {
"oneOf": [
{ "$ref": "#/definitions/Account" },
{ "$ref": "#/definitions/ActivityDefinition" },
...
]
}
I've tried declaring the 'resource' variable as types 'var', 'dynamic', and 'ResourceList' and created a class ResourceList that just contains a resource.
Each resource has a field titled 'resourceType', so I've also tried creating a ResourceList function that returns different types based on argument of 'resourceType', which also doesn't work.
If I do an http request, the actual response I'm trying to parse looks like this:
{
"resourceType": "Bundle",
"type": "searchset",
"entry": [
{
"resource": {
"name": "Jaba the Hutt"
"birthDate": "1980-07-27",
"id": "b26646dd-c549-4981-834e-bb4145d104b8",
"resourceType": "Patient"
}
}
]
}
Any suggestions would be appreciated.
Updating my question. It's interesting, that the first answer is similar to what I've come up with currently.
class Bundle_Entry {
dynamic resource;
Bundle_Entry({this.resource});
Bundle_Entry.fromJson(Map<String, dynamic> json) =>
Bundle_Entry(
resource: json['resource'] == null
? null
: ResourceTypes(
json['resource']['resourceType'], json['resource'] as Map<String, dynamic>)
);}
Map<String, dynamic> toJson() => _$Bundle_EntryToJson(this);
}
dynamic ResourceTypes(String type, Map<String, dynamic> json) {
if (type == 'Element') return (new Element.fromJson(json));
if (type == 'Extension') return (new Extension.fromJson(json));
if (type == 'Patient') return (new Narrative.fromJson(json));
My issue is that then I have to hard code each ResourceType, and it seemed like there should be an easier way.
I have been trying to build a similar thing. I approached it using inheritance and created a function to return the resource based on the ResourceType field.
Resource getResource(json) {
if(json == null) return null;
if(json["resourceType"] == "Patient") return Patient.fromJson(json);
if(json["resourceType"]=="Procedure") return Procedure.fromJson(json);
if(json["resourceType"]=="Encounter") return Encounter.fromJson(json);
if(json["resourceType"]=="Appointment") return Appointment.fromJson(json);
if(json["resourceType"]=="Slot") return Slot.fromJson(json);
if(json["resourceType"]=="Slot") return Slot.fromJson(json);
if(json["resourceType"]=="Observation") return Observation.fromJson(json);
if(json["resourceType"]=="Condition") return Condition.fromJson(json);
if(json["resourceType"]=="DiagnosticReport") return DiagnosticReport.fromJson(json);
if(json["resourceType"]=="MedicationRequest") return MedicationRequest.fromJson(json);
if(json["resourceType"]=="CarePlan") return CarePlan.fromJson(json);
if(json["resourceType"]=="Practitioner") return Practitioner.fromJson(json);
if(json["resourceType"]=="AllergyIntolerance") return AllergyIntolerance.fromJson(json);
return Resource.fromJson(json);
}
Where Patient, Procedure, etc. are subclasses of Resource:
class Entry {
String fullUrl;
Resource resource;
factory Entry.fromJson(Map<String, dynamic> json) => Entry(
fullUrl: json["fullUrl"] == null ? null : json["fullUrl"],
//This line is the magic
resource: getResource(json["resource"]),
search: json["search"] == null ? null : Search.fromJson(json["search"]),
response: json["response"] == null
? null
: Response.fromJson(json["response"]),
);