i have my api which returns the json data, within the json there is multiple nested parts that i want to use. i have my models setup. how do i return them back to my futurebuilder and then use them i.e.
snapshot.data['media'][0].fieldname or snapshot.data['locationData'][0].fieldname.
I have change the code back so at the moment it only returns the LocationData but not the MediaData. this is the part i need help with returning all of it at the same time to use on my page.
here is what the json looks like when i get it back from the api
{
"recordsTotal": 1,
"sensordate": "2022-01-20",
"data": [
{
"id": 2,
"locationname": "The Old Man of Storr",
"description": "",
"shortdescription":"",
"latitude": "55.9486",
"longitude": " -3.1910",
"mainimageurl": "",
"road": "",
"addressline1": "",
"addressline2": "",
"town": "",
"county": "",
"postcode": "",
"areaid": 2,
"headerimageid": 450,
"carparkcapacity": 100,
"title": "Old Town",
"originalfilename": "OldTown.jpg",
"ext": "jpg",
"alttext": "Old Town",
"savelocation": "/library/images/locations/",
"filename": "cd8d5c511f3b64758238e75c1aa7c84d"
}
],
"media": [
{
"locationid": 2,
"mediaid": 32,
"title": "Old Town History",
"systemfilename": "/library/media/64c8ba08a781ef8b8b2a08c62d0427b6.mp3",
"transcriptionnotes": "Transcription of media file",
"mediatype": "audio",
"originalfilename": "oldtown.mp3",
"locationname": "Old Town"
}
]
}
//This is my 2 models
class LocationData {
final int id;
final String locationname;
final String description;
final String shortdescription;
final double latitude;
final double longitude;
final String mainimageurl;
final String imagefilename;
final String imagelocation;
final String imageext;
final int carparkcapacity;
final int areaid;
LocationData(
{required this.id,
required this.locationname,
required this.description,
required this.carparkcapacity,
required this.areaid,
required this.imageext,
required this.imagefilename,
required this.imagelocation,
required this.latitude,
required this.longitude,
required this.mainimageurl,
required this.shortdescription,
});
factory LocationData.fromJson(json) => LocationData(
locationname: json['locationname'],
id: json['id'] == null ? 0 : json["id"],
latitude: double.parse(json['latitude']),
longitude: double.parse(json['longitude']),
areaid: json['areaid'] == null ? 0 : json["areaid"],
description: json['description'] == null
? 'Welcome to Skye'
: json["description"],
shortdescription: json['shortdescription'] == null
? 'Welcome'
: json["shortdescription"],
imageext: json['ext'] == null ? 'jpg' : json["ext"],
carparkcapacity:
json['carparkcapacity'] == null ? 0 : json["carparkcapacity"],
imagefilename:
json['filename'] == null ? 'logo' : json["filename"],
imagelocation: json['savelocation'] == null
? '/assets/imgs/'
: json["savelocation"],
mainimageurl: json['mainimageurl'] == null
? '/assets/imgs/logo.jpg'
: json["mainimageurl"],
);
}
//Similar to above
class MediaData{}
//Getting the data
class LocationDataApi {
static Future<List<LocationData>> getLocationData(
String locationName) async {
final hotspotLocationsURL =
'${config.apiUrl}/locations.php?action=get_location&location=' +
locationName;
try {
final response = await http.get(Uri.parse(hotspotLocationsURL));
if (response.statusCode == 200) {
final body = json.decode(response.body);
//Returned Data
return body['data'].map<LocationData>(LocationData.fromJson).toList();
} else {
throw 'Error Retrieving Data';
}
} catch (e) {
if (kDebugMode) {
print(e);
}
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load Location Data');
}
}
}
on my page
class _AlreadyHereState extends State<AlreadyHere> {
late Future<List<LocationData>> _locationData;
}
....other code
FutureBuilder(
future: _locationData,
builder: (BuildContext context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.error != null) {
return const Center(child: Text('an error occured!'));
} else {
//this part how do i get the data? snapshot.data['media'][0].fieldname doesnt work/
for starters, you can change your model to look this
// To parse this JSON data, do
//
// final someClass = someClassFromJson(jsonString);
import 'package:meta/meta.dart';
import 'dart:convert';
class SomeClass {
SomeClass({
required this.recordsTotal,
required this.sensordate,
required this.data,
required this.media,
});
final int recordsTotal;
final DateTime sensordate;
final List<Datum> data;
final List<Media> media;
factory SomeClass.fromRawJson(String str) => SomeClass.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory SomeClass.fromJson(Map<String, dynamic> json) => SomeClass(
recordsTotal: json["recordsTotal"],
sensordate: DateTime.parse(json["sensordate"]),
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
media: List<Media>.from(json["media"].map((x) => Media.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"recordsTotal": recordsTotal,
"sensordate": "${sensordate.year.toString().padLeft(4, '0')}-${sensordate.month.toString().padLeft(2, '0')}-${sensordate.day.toString().padLeft(2, '0')}",
"data": List<dynamic>.from(data.map((x) => x.toJson())),
"media": List<dynamic>.from(media.map((x) => x.toJson())),
};
}
class Datum {
Datum({
required this.id,
required this.locationname,
required this.description,
required this.shortdescription,
required this.latitude,
required this.longitude,
required this.mainimageurl,
required this.road,
required this.addressline1,
required this.addressline2,
required this.town,
required this.county,
required this.postcode,
required this.areaid,
required this.headerimageid,
required this.carparkcapacity,
required this.title,
required this.originalfilename,
required this.ext,
required this.alttext,
required this.savelocation,
required this.filename,
});
final int id;
final String locationname;
final String description;
final String shortdescription;
final String latitude;
final String longitude;
final String mainimageurl;
final String road;
final String addressline1;
final String addressline2;
final String town;
final String county;
final String postcode;
final int areaid;
final int headerimageid;
final int carparkcapacity;
final String title;
final String originalfilename;
final String ext;
final String alttext;
final String savelocation;
final String filename;
factory Datum.fromRawJson(String str) => Datum.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
locationname: json["locationname"],
description: json["description"],
shortdescription: json["shortdescription"],
latitude: json["latitude"],
longitude: json["longitude"],
mainimageurl: json["mainimageurl"],
road: json["road"],
addressline1: json["addressline1"],
addressline2: json["addressline2"],
town: json["town"],
county: json["county"],
postcode: json["postcode"],
areaid: json["areaid"],
headerimageid: json["headerimageid"],
carparkcapacity: json["carparkcapacity"],
title: json["title"],
originalfilename: json["originalfilename"],
ext: json["ext"],
alttext: json["alttext"],
savelocation: json["savelocation"],
filename: json["filename"],
);
Map<String, dynamic> toJson() => {
"id": id,
"locationname": locationname,
"description": description,
"shortdescription": shortdescription,
"latitude": latitude,
"longitude": longitude,
"mainimageurl": mainimageurl,
"road": road,
"addressline1": addressline1,
"addressline2": addressline2,
"town": town,
"county": county,
"postcode": postcode,
"areaid": areaid,
"headerimageid": headerimageid,
"carparkcapacity": carparkcapacity,
"title": title,
"originalfilename": originalfilename,
"ext": ext,
"alttext": alttext,
"savelocation": savelocation,
"filename": filename,
};
}
class Media {
Media({
required this.locationid,
required this.mediaid,
required this.title,
required this.systemfilename,
required this.transcriptionnotes,
required this.mediatype,
required this.originalfilename,
required this.locationname,
});
final int locationid;
final int mediaid;
final String title;
final String systemfilename;
final String transcriptionnotes;
final String mediatype;
final String originalfilename;
final String locationname;
factory Media.fromRawJson(String str) => Media.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory Media.fromJson(Map<String, dynamic> json) => Media(
locationid: json["locationid"],
mediaid: json["mediaid"],
title: json["title"],
systemfilename: json["systemfilename"],
transcriptionnotes: json["transcriptionnotes"],
mediatype: json["mediatype"],
originalfilename: json["originalfilename"],
locationname: json["locationname"],
);
Map<String, dynamic> toJson() => {
"locationid": locationid,
"mediaid": mediaid,
"title": title,
"systemfilename": systemfilename,
"transcriptionnotes": transcriptionnotes,
"mediatype": mediatype,
"originalfilename": originalfilename,
"locationname": locationname,
};
}
and then inside FutureBuilder use like this
FutureBuilder(
future: _locationData,
// Add <T> to the Asyncsnapshot class
builder: (BuildContext context, AsyncSnapshot<SomeClass> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.error != null) {
return const Center(child: Text('an error occured!'));
} else {
print(snapshot.data.data[0].longitude);
print(snapshot.data.media[0].title);
}
Related
When I start the project I got an unexpected null value.
I keep getting this error with this API, I don't have certain of what can be.
you can check here
api link: https://ffxivcollect.com/api/mounts/257
response
{
"id": 257,
"name": "Island Eggplant Knight",
"description": "Summon forth your island Eggplant Knight, an oversized vegetable embodiment of chivalry.",
"enhanced_description": "Hailing from the selfsame land as the Tomato King, the Eggplant Knight shared a crate with the sovereign when they were shipped out. However, he fell overboard when the vessel encountered rough seas, and drifted for days before being deposited on a desert island. Among other feats, he prides himself on having played a key role in the founding of the West Mandra Empire.",
"tooltip": "I thought ye were a feral turnip, a murderous eggplant, or summat like that! - Tiny Trader",
"movement": "Terrestrial",
"seats": 1,
"order": 240,
"order_group": 99,
"patch": "6.2",
"item_id": null,
"tradeable": false,
"owned": "3.9%",
"image": "https://ffxivcollect.com/images/mounts/large/257.png",
"icon": "https://ffxivcollect.com/images/mounts/small/257.png",
"bgm": "https://ffxivcollect.com/music/BGM_Ride_MJI.ogg",
"sources": [
{
"type": "Purchase",
"text": "12,000 Seafarer's Cowries",
"related_type": null,
"related_id": null
}
]
}
I'm using quick type to convert the JSON to dart and paste in the model only adding Required.
my home page:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(''),
),
body: ListView.builder(
itemCount: finalApi!.length,
itemBuilder: (context, index) {
return Container(
child: Text(finalApi![index].description),
);
},
),
);
}
}
url:
class RemoteService {
Future<List<FinalApi>> getPosts() async {
var client = http.Client();
var uri = Uri.parse('https://ffxivcollect.com/api/mounts/257');
var response = await client.get(uri);
if (response.statusCode == 200) {
var json = response.body;
return finalApiFromJson(json);
}
throw Text('aa');
}
}
my model:
List<FinalApi> finalApiFromJson(String str) =>
List<FinalApi>.from(json.decode(str).map((x) => FinalApi.fromJson(x)));
String finalApiToJson(List<FinalApi> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class FinalApi {
FinalApi({
required this.id,
required this.name,
required this.description,
required this.enhancedDescription,
required this.tooltip,
required this.movement,
required this.seats,
required this.order,
required this.orderGroup,
required this.patch,
required this.itemId,
required this.tradeable,
required this.owned,
required this.image,
required this.icon,
required this.bgm,
required this.sources,
});
int id;
String name;
String description;
String enhancedDescription;
String tooltip;
String movement;
int seats;
int order;
int orderGroup;
String patch;
dynamic itemId;
bool tradeable;
String owned;
String image;
String icon;
String bgm;
List<Source> sources;
factory FinalApi.fromJson(Map<String, dynamic> json) => FinalApi(
id: json["id"],
name: json["name"],
description: json["description"],
enhancedDescription: json["enhanced_description"],
tooltip: json["tooltip"],
movement: json["movement"],
seats: json["seats"],
order: json["order"],
orderGroup: json["order_group"],
patch: json["patch"],
itemId: json["item_id"],
tradeable: json["tradeable"],
owned: json["owned"],
image: json["image"],
icon: json["icon"],
bgm: json["bgm"],
sources:
List<Source>.from(json["sources"].map((x) => Source.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"description": description,
"enhanced_description": enhancedDescription,
"tooltip": tooltip,
"movement": movement,
"seats": seats,
"order": order,
"order_group": orderGroup,
"patch": patch,
"item_id": itemId,
"tradeable": tradeable,
"owned": owned,
"image": image,
"icon": icon,
"bgm": bgm,
"sources": List<dynamic>.from(sources.map((x) => x.toJson())),
};
}
class Source {
Source({
required this.type,
required this.text,
required this.relatedType,
required this.relatedId,
});
String type;
String text;
dynamic relatedType;
dynamic relatedId;
factory Source.fromJson(Map<String, dynamic> json) => Source(
type: json["type"],
text: json["text"],
relatedType: json["related_type"],
relatedId: json["related_id"],
);
Map<String, dynamic> toJson() => {
"type": type,
"text": text,
"related_type": relatedType,
"related_id": relatedId,
};
}
Based on your response, It is returning a single item on map. Therefor the parser will be like
final data = FinalApi.fromJson(jsonDecode(json));
class RemoteService {
Future<List<FinalApi>> getPosts() async {
var client = http.Client();
var uri = Uri.parse('https://ffxivcollect.com/api/mounts/257');
var response = await client.get(uri);
try {
if (response.statusCode == 200) {
var json = response.body;
// finalApiFromJson(json);
final data = FinalApi.fromJson(jsonDecode(json));
return [data];
}
} catch (e) {
log(e.toString());
}
return [];
}
}
I am trying to get current weather info from OpenWeather and display the result in Text Widget after checking that there is data returned. However, that condtion (snapshot.hasData) is always returned as false and else condition (CircularProgressIndicator) is invoked.
Here is the FutureBuilder.
class WeatherPage extends StatefulWidget {
#override
State<WeatherPage> createState() => _WeatherPageState();
}
class _WeatherPageState extends State<WeatherPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FutureBuilder(
future: getCurrentWeather(),
builder: (context, snapshot) {
if (snapshot.hasData) {
WeatherModelCurrent weather =
snapshot.data as WeatherModelCurrent;
return weatherBox(weather);
} else {
return const CircularProgressIndicator();
}
},
),
),
);
}
here is the getCurrentWeather() function
Future getCurrentWeather() async {
WeatherModelCurrent? weather;
var url = Uri.parse(
"https://api.openweathermap.org/data/2.5/weather?q=Kathmandu&appid=82c7b99e2a8215351147f607592a3e63&units=metric");
var response = await http.get(url);
//response.body has the data returned by API call
print(response.body);
if (response.statusCode == 200) {
weather = WeatherModelCurrent.frommJson(jsonDecode(response.body));
} else {
print('error');
}
return weather;
}
and here is the model class
class WeatherModelCurrent {
double temp;
double feelslike;
double tempmin;
double tempmax;
String description;
WeatherModelCurrent(
{required this.temp,
required this.feelslike,
required this.tempmin,
required this.tempmax,
required this.description});
factory WeatherModelCurrent.frommJson(Map<String, dynamic> jsonn) {
return WeatherModelCurrent(
temp: jsonn['main']['temp'].toDouble(),
feelslike: jsonn['main']['feels_like'].toDouble(),
tempmin: jsonn['main']['temp_min'].toDouble(),
tempmax: jsonn['main']['temp_max'].toDouble(),
description: jsonn['weather']['description'],
);
}
}
Try & catch your getCurrentWeather code block, we can get the following exception:
flutter: exception type 'String' is not a subtype of type 'int' of 'index'
The response json is like:
{
"weather":[
{
"id":803,
"main":"Clouds",
"description":"broken clouds",
"icon":"04d"
}
],
}
Your code description: jsonn['weather']['description'] should be description: jsonn['weather'][0]['description'],
The error is occur because you parse your response.body in wrong class.
Try this model class
class WeatherModelCurrent {
WeatherModelCurrent({
this.coord,
this.weather,
this.base,
this.main,
this.visibility,
this.wind,
this.clouds,
this.dt,
this.sys,
this.timezone,
this.id,
this.name,
this.cod,
});
final Coord? coord;
final List<Weather>? weather;
final String? base;
final Main? main;
final int? visibility;
final Wind? wind;
final Clouds? clouds;
final int? dt;
final Sys? sys;
final int? timezone;
final int? id;
final String? name;
final int? cod;
factory WeatherModelCurrent.fromJson(Map<String, dynamic> json) => WeatherModelCurrent(
coord: Coord.fromJson(json["coord"]),
weather: List<Weather>.from(json["weather"].map((x) => Weather.fromJson(x))),
base: json["base"],
main: Main.fromJson(json["main"]),
visibility: json["visibility"],
wind: Wind.fromJson(json["wind"]),
clouds: Clouds.fromJson(json["clouds"]),
dt: json["dt"],
sys: Sys.fromJson(json["sys"]),
timezone: json["timezone"],
id: json["id"],
name: json["name"],
cod: json["cod"],
);
Map<String, dynamic> toJson() => {
"coord": coord!.toJson(),
"weather": List<dynamic>.from(weather!.map((x) => x.toJson())),
"base": base,
"main": main!.toJson(),
"visibility": visibility,
"wind": wind!.toJson(),
"clouds": clouds!.toJson(),
"dt": dt,
"sys": sys!.toJson(),
"timezone": timezone,
"id": id,
"name": name,
"cod": cod,
};
}
class Clouds {
Clouds({
this.all,
});
final int? all;
factory Clouds.fromJson(Map<String, dynamic> json) => Clouds(
all: json["all"],
);
Map<String, dynamic> toJson() => {
"all": all,
};
}
class Coord {
Coord({
this.lon,
this.lat,
});
final double? lon;
final double? lat;
factory Coord.fromJson(Map<String, dynamic> json) => Coord(
lon: json["lon"].toDouble(),
lat: json["lat"].toDouble(),
);
Map<String, dynamic> toJson() => {
"lon": lon,
"lat": lat,
};
}
class Main {
Main({
this.temp,
this.feelsLike,
this.tempMin,
this.tempMax,
this.pressure,
this.humidity,
});
final double? temp;
final double? feelsLike;
final double? tempMin;
final double? tempMax;
final int? pressure;
final int? humidity;
factory Main.fromJson(Map<String, dynamic> json) => Main(
temp: json["temp"].toDouble(),
feelsLike: json["feels_like"].toDouble(),
tempMin: json["temp_min"].toDouble(),
tempMax: json["temp_max"].toDouble(),
pressure: json["pressure"],
humidity: json["humidity"],
);
Map<String, dynamic> toJson() => {
"temp": temp,
"feels_like": feelsLike,
"temp_min": tempMin,
"temp_max": tempMax,
"pressure": pressure,
"humidity": humidity,
};
}
class Sys {
Sys({
this.type,
this.id,
this.country,
this.sunrise,
this.sunset,
});
final int? type;
final int? id;
final String? country;
final int? sunrise;
final int? sunset;
factory Sys.fromJson(Map<String, dynamic> json) => Sys(
type: json["type"],
id: json["id"],
country: json["country"],
sunrise: json["sunrise"],
sunset: json["sunset"],
);
Map<String, dynamic> toJson() => {
"type": type,
"id": id,
"country": country,
"sunrise": sunrise,
"sunset": sunset,
};
}
class Weather {
Weather({
this.id,
this.main,
this.description,
this.icon,
});
final int? id;
final String? main;
final String? description;
final String? icon;
factory Weather.fromJson(Map<String, dynamic> json) => Weather(
id: json["id"],
main: json["main"],
description: json["description"],
icon: json["icon"],
);
Map<String, dynamic> toJson() => {
"id": id,
"main": main,
"description": description,
"icon": icon,
};
}
class Wind {
Wind({
this.speed,
this.deg,
});
final double? speed;
final int? deg;
factory Wind.fromJson(Map<String, dynamic> json) => Wind(
speed: json["speed"].toDouble(),
deg: json["deg"],
);
Map<String, dynamic> toJson() => {
"speed": speed,
"deg": deg,
};
}
I want to deserialize some JSON data that contains a list of article information
{
"data": [
{
"id": 1,
"title": "First article",
"createdDate": "2022-03-20T11:46:00",
"content": "Markdown content",
"author": 1,
"category": 1
},
{
"id": 2,
"title": "Second article",
"createdDate": "2022-03-20T11:46:00",
"content": "Markdown content",
"author": 1,
"category": 1
}
]
}
No matter what the request is, the top level will have a key called data
So, I created a generic class called Entry
import 'package:json_annotation/json_annotation.dart';
part 'Entry.g.dart';
#JsonSerializable(genericArgumentFactories: true)
class Entry<TData> {
Entry(this.data);
TData data;
factory Entry.fromJson(Map<String, dynamic> json,TData Function(dynamic json) fromJsonTData) => _$EntryFromJson(json,fromJsonTData);
Map<String, dynamic> toJson(Object? Function(TData value) toJsonTData) => _$EntryToJson(this,toJsonTData);
}
And for an article, I created a class call NovelData
import 'dart:convert';
import 'dart:core';
import 'package:json_annotation/json_annotation.dart';
import 'Entry.dart';
part 'NovelData.g.dart';
#JsonSerializable(genericArgumentFactories: true)
class NovelData {
NovelData(this.id, this.title, this.createdDate, this.content, this.author, this.category);
int id;
String title;
String createdDate;
String content;
int author;
int category;
factory NovelData.fromJson(Map<String, dynamic> json) =>
_$NovelDataFromJson(json);
Map<String, dynamic> toJson() => _$NovelDataToJson(this);
}
Now, if I want to use the type like Entry<List<Novel>>> to deserialize the above JSON data, what should I do?
You can access them through the full path to the data.
Full path to your data: Map => key data => Array => Array index => Map
{}.data.[].0.{}
It only takes one class.
import 'package:fast_json/fast_json_selector.dart' as parser;
void main() async {
final path = '{}.data.[].0.{}';
final pathLevel = path.split('.').length;
final items = <Novel>[];
void select(parser.JsonSelectorEvent event) {
if (event.levels.length == pathLevel) {
if (event.levels.join('.') == path) {
final item = Novel.fromJson(event.lastValue as Map);
items.add(item);
event.lastValue = null;
}
}
}
parser.parse(_json, select: select);
print(items.join('\n'));
}
final _json = '''
{
"data": [
{
"id": 1,
"title": "First article",
"createdDate": "2022-03-20T11:46:00",
"content": "Markdown content",
"author": 1,
"category": 1
},
{
"id": 2,
"title": "Second article",
"createdDate": "2022-03-20T11:46:00",
"content": "Markdown content",
"author": 1,
"category": 1
}
]
}''';
class Novel {
final int id;
final String title;
Novel({required this.id, required this.title});
#override
String toString() {
return title;
}
static Novel fromJson(Map json) {
return Novel(
id: json['id'] as int,
title: json['title'] as String,
);
}
}
Output:
First article
Second article
You can get the data before adding it to the list. The result is no different. Just a different path to the data.
void main() async {
final path = '{}.data.[].0';
final pathLevel = path.split('.').length;
final items = <Novel>[];
void select(parser.JsonSelectorEvent event) {
if (event.levels.length == pathLevel) {
if (event.levels.join('.') == path) {
final item = Novel.fromJson(event.lastValue as Map);
items.add(item);
event.lastValue = null;
}
}
}
parser.parse(_json, select: select);
print(items.join('\n'));
}
This event follows the object creation event (at a lower event level):
JsonHandlerEvent.endObject => JsonHandlerEvent.element
You can get the data after adding it to the list. But it won't be as efficient.
void main() async {
final path = '{}.data.[]';
final pathLevel = path.split('.').length;
final items = <Novel>[];
void select(parser.JsonSelectorEvent event) {
if (event.levels.length == pathLevel) {
if (event.levels.join('.') == path) {
final list = event.lastValue as List;
items.addAll(list.map((e) => Novel.fromJson(e as Map)));
list.clear();
}
}
}
parser.parse(_json, select: select);
print(items.join('\n'));
}
JsonHandlerEvent.endObject => JsonHandlerEvent.element => JsonHandlerEvent.endArray
Or even from property data. Very inefficient because all data is stored in memory.
void main() async {
final path = '{}.data';
final pathLevel = path.split('.').length;
final items = <Novel>[];
void select(parser.JsonSelectorEvent event) {
if (event.levels.length == pathLevel) {
if (event.levels.join('.') == path) {
final list = event.lastValue as List;
items.addAll(list.map((e) => Novel.fromJson(e as Map)));
event.lastValue = null;
}
}
}
parser.parse(_json, select: select);
print(items.join('\n'));
}
JsonHandlerEvent.endObject => JsonHandlerEvent.element => JsonHandlerEvent.endArray => JsonHandlerEvent.endKey
I won't even write about the last level. There is no point in such an inefficient way. However, and in the previous one, too.
JsonHandlerEvent.endObject => JsonHandlerEvent.element => JsonHandlerEvent.endArray => JsonHandlerEvent.endKey => JsonHandlerEvent.endObject
There is a website which automatically generates all needed code from json. Here is example:
// To parse this JSON data, do
//
// final entry = entryFromJson(jsonString);
import 'dart:convert';
Entry entryFromJson(String str) => Entry.fromJson(json.decode(str));
String entryToJson(Entry data) => json.encode(data.toJson());
class Entry {
Entry({
this.data,
});
List<Datum> data;
factory Entry.fromJson(Map<String, dynamic> json) => Entry(
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
this.id,
this.title,
this.createdDate,
this.content,
this.author,
this.category,
});
int id;
String title;
DateTime createdDate;
String content;
int author;
int category;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
title: json["title"],
createdDate: DateTime.parse(json["createdDate"]),
content: json["content"],
author: json["author"],
category: json["category"],
);
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"createdDate": createdDate.toIso8601String(),
"content": content,
"author": author,
"category": category,
};
}
you can try my jsonize package, it will handle any of your TData classes wherever they are in your Entry data list
import 'package:jsonize/jsonize.dart';
abstract class TData {}
class Entry implements Jsonizable {
Entry({
required this.data,
});
factory Entry.empty() => Entry(data: []);
List<TData> data;
#override
String get jsonClassCode => "Entry";
#override
Entry fromJson(json) => Entry(data: List<TData>.from(json["data"]));
#override
Map<String, dynamic> toJson() => {"data": data};
}
class NovelData extends TData implements Jsonizable {
NovelData({
required this.id,
required this.title,
required this.createdDate,
required this.content,
required this.author,
required this.category,
});
factory NovelData.empty() => NovelData(
id: 0,
title: "",
createdDate: DateTime(0),
content: "",
author: 0,
category: 0);
int id;
String title;
DateTime createdDate;
String content;
int author;
int category;
#override
String get jsonClassCode => "NovelData";
#override
NovelData fromJson(json) => NovelData(
id: json["id"],
title: json["title"],
createdDate: json["createdDate"],
content: json["content"],
author: json["author"],
category: json["category"],
);
#override
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"createdDate": createdDate,
"content": content,
"author": author,
"category": category,
};
}
main() {
Jsonize.registerClass(Entry.empty());
Jsonize.registerClass(NovelData.empty());
NovelData novel1 = NovelData(
id: 1,
title: "First article",
createdDate: DateTime.now(),
content: "Markdown content",
author: 1,
category: 1);
NovelData novel2 = NovelData(
id: 2,
title: "Second article",
createdDate: DateTime.now(),
content: "Markdown content",
author: 1,
category: 1);
Entry myEntry = Entry(data: [novel1, novel2]);
String myEntryJson = Jsonize.toJson(myEntry);
print(myEntryJson);
Entry entryBackToLife = Jsonize.fromJson(myEntryJson);
print(entryBackToLife);
}
jsonize can do more like handling enums. In your case benefits are:
DateTime serialization is handled by jsonize, you don not need to transform it
You can derive new classes from TData and put them into your Entry, jsonize will handle them and automatically transform it back to the original class
I'm trying to get data from JSON, the data is as follows :
For the JSON above, I've generated a Dart Class using this website
the code below works fine with this response : RESPONSE TVSHOW DETAILS, I can see all data loaded successfully in my app, but not with this one RESPONSE TVSHOW DETAILS 2, nothing is loaded
TVShow tvShowFromJson(String str) => TVShow.fromJson(json.decode(str));
String tvShowToJson(TVShow data) => json.encode(data.toJson());
class TVShow {
String backdropPath;
List<CreatedBy> createdBy;
List<int> episodeRunTime;
DateTime firstAirDate;
List<Genre> genres;
String homepage;
int id;
bool inProduction;
List<String> languages;
DateTime lastAirDate;
TEpisodeToAir lastEpisodeToAir;
String name;
TEpisodeToAir nextEpisodeToAir;
List<Network> networks;
int numberOfEpisodes;
int numberOfSeasons;
List<String> originCountry;
String originalLanguage;
String originalName;
String overview;
double popularity;
String posterPath;
List<Network> productionCompanies;
List<Season> seasons;
String status;
String type;
double voteAverage;
int voteCount;
TVShow({
this.backdropPath,
this.createdBy,
this.episodeRunTime,
this.firstAirDate,
this.genres,
this.homepage,
this.id,
this.inProduction,
this.languages,
this.lastAirDate,
this.lastEpisodeToAir,
this.name,
this.nextEpisodeToAir,
this.networks,
this.numberOfEpisodes,
this.numberOfSeasons,
this.originCountry,
this.originalLanguage,
this.originalName,
this.overview,
this.popularity,
this.posterPath,
this.productionCompanies,
this.seasons,
this.status,
this.type,
this.voteAverage,
this.voteCount,
});
factory TVShow.fromJson(Map<String, dynamic> json) => TVShow(
backdropPath: json["backdrop_path"],
createdBy: List<CreatedBy>.from(json["created_by"].map((x) => CreatedBy.fromJson(x))),
episodeRunTime: List<int>.from(json["episode_run_time"].map((x) => x)),
firstAirDate: DateTime.parse(json["first_air_date"]),
genres: List<Genre>.from(json["genres"].map((x) => Genre.fromJson(x))),
homepage: json["homepage"],
id: json["id"],
inProduction: json["in_production"],
languages: List<String>.from(json["languages"].map((x) => x)),
lastAirDate: DateTime.parse(json["last_air_date"]),
lastEpisodeToAir: TEpisodeToAir.fromJson(json["last_episode_to_air"]),
name: json["name"],
nextEpisodeToAir: TEpisodeToAir.fromJson(json["next_episode_to_air"]),
networks: List<Network>.from(json["networks"].map((x) => Network.fromJson(x))),
numberOfEpisodes: json["number_of_episodes"],
numberOfSeasons: json["number_of_seasons"],
originCountry: List<String>.from(json["origin_country"].map((x) => x)),
originalLanguage: json["original_language"],
originalName: json["original_name"],
overview: json["overview"],
popularity: json["popularity"].toDouble(),
posterPath: json["poster_path"],
productionCompanies: List<Network>.from(json["production_companies"].map((x) => Network.fromJson(x))),
seasons: List<Season>.from(json["seasons"].map((x) => Season.fromJson(x))),
status: json["status"],
type: json["type"],
voteAverage: json["vote_average"].toDouble(),
voteCount: json["vote_count"],
);
Map<String, dynamic> toJson() => {
"backdrop_path": backdropPath,
"created_by": List<dynamic>.from(createdBy.map((x) => x.toJson())),
"episode_run_time": List<dynamic>.from(episodeRunTime.map((x) => x)),
"first_air_date":
"${firstAirDate.year.toString().padLeft(4, '0')}-${firstAirDate.month.toString().padLeft(2, '0')}-${firstAirDate.day.toString().padLeft(2, '0')}",
"genres": List<dynamic>.from(genres.map((x) => x.toJson())),
"homepage": homepage,
"id": id,
"in_production": inProduction,
"languages": List<dynamic>.from(languages.map((x) => x)),
"last_air_date":
"${lastAirDate.year.toString().padLeft(4, '0')}-${lastAirDate.month.toString().padLeft(2, '0')}-${lastAirDate.day.toString().padLeft(2, '0')}",
"last_episode_to_air": lastEpisodeToAir.toJson(),
"name": name,
"next_episode_to_air": nextEpisodeToAir.toJson(),
"networks": List<dynamic>.from(networks.map((x) => x.toJson())),
"number_of_episodes": numberOfEpisodes,
"number_of_seasons": numberOfSeasons,
"origin_country": List<dynamic>.from(originCountry.map((x) => x)),
"original_language": originalLanguage,
"original_name": originalName,
"overview": overview,
"popularity": popularity,
"poster_path": posterPath,
"production_companies": List<dynamic>.from(productionCompanies.map((x) => x.toJson())),
"seasons": List<dynamic>.from(seasons.map((x) => x.toJson())),
"status": status,
"type": type,
"vote_average": voteAverage,
"vote_count": voteCount,
};
}
class CreatedBy {
int id;
String creditId;
String name;
int gender;
String profilePath;
CreatedBy({
this.id,
this.creditId,
this.name,
this.gender,
this.profilePath,
});
factory CreatedBy.fromJson(Map<String, dynamic> json) => CreatedBy(
id: json["id"],
creditId: json["credit_id"],
name: json["name"],
gender: json["gender"],
profilePath: json["profile_path"],
);
Map<String, dynamic> toJson() => {
"id": id,
"credit_id": creditId,
"name": name,
"gender": gender,
"profile_path": profilePath,
};
}
class Genre {
int id;
String name;
Genre({
this.id,
this.name,
});
factory Genre.fromJson(Map<String, dynamic> json) => Genre(
id: json["id"],
name: json["name"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
};
}
class TEpisodeToAir {
DateTime airDate;
int episodeNumber;
int id;
String name;
String overview;
String productionCode;
int seasonNumber;
int showId;
String stillPath;
double voteAverage;
int voteCount;
TEpisodeToAir({
this.airDate,
this.episodeNumber,
this.id,
this.name,
this.overview,
this.productionCode,
this.seasonNumber,
this.showId,
this.stillPath,
this.voteAverage,
this.voteCount,
});
factory TEpisodeToAir.fromJson(Map<String, dynamic> json) => TEpisodeToAir(
airDate: DateTime.parse(json["air_date"]),
episodeNumber: json["episode_number"],
id: json["id"],
name: json["name"],
overview: json["overview"],
productionCode: json["production_code"],
seasonNumber: json["season_number"],
showId: json["show_id"],
stillPath: json["still_path"],
voteAverage: json["vote_average"].toDouble(),
voteCount: json["vote_count"],
);
Map<String, dynamic> toJson() => {
"air_date":
"${airDate.year.toString().padLeft(4, '0')}-${airDate.month.toString().padLeft(2, '0')}-${airDate.day.toString().padLeft(2, '0')}",
"episode_number": episodeNumber,
"id": id,
"name": name,
"overview": overview,
"production_code": productionCode,
"season_number": seasonNumber,
"show_id": showId,
"still_path": stillPath,
"vote_average": voteAverage,
"vote_count": voteCount,
};
}
class Network {
String name;
int id;
String logoPath;
String originCountry;
Network({
this.name,
this.id,
this.logoPath,
this.originCountry,
});
factory Network.fromJson(Map<String, dynamic> json) => Network(
name: json["name"],
id: json["id"],
logoPath: json["logo_path"] == null ? null : json["logo_path"],
originCountry: json["origin_country"],
);
Map<String, dynamic> toJson() => {
"name": name,
"id": id,
"logo_path": logoPath == null ? null : logoPath,
"origin_country": originCountry,
};
}
class Season {
DateTime airDate;
int episodeCount;
int id;
String name;
String overview;
String posterPath;
int seasonNumber;
Season({
this.airDate,
this.episodeCount,
this.id,
this.name,
this.overview,
this.posterPath,
this.seasonNumber,
});
factory Season.fromJson(Map<String, dynamic> json) => Season(
airDate: DateTime.parse(json["air_date"]),
episodeCount: json["episode_count"],
id: json["id"],
name: json["name"],
overview: json["overview"],
posterPath: json["poster_path"],
seasonNumber: json["season_number"],
);
Map<String, dynamic> toJson() => {
"air_date":
"${airDate.year.toString().padLeft(4, '0')}-${airDate.month.toString().padLeft(2, '0')}-${airDate.day.toString().padLeft(2, '0')}",
"episode_count": episodeCount,
"id": id,
"name": name,
"overview": overview,
"poster_path": posterPath,
"season_number": seasonNumber,
};
}
When I tried to catch the error with :
if (snapshot.hasError) {
print('ERROR : ${snapshot.error}');
}
I got this :
I/flutter (16719): ERROR : NoSuchMethodError: The method '[]' was
called on null. I/flutter (16719): Receiver: null I/flutter (16719):
Tried calling: []("air_date")
It could be because the "next_episode_to_air" parameter in the second link (TV show details 2) is actually a null value! You can check for nulls using ?? operator in Dart.
You can have a look at its usage here
In your case, you could use it like this in your TVShow.fromJson method,
nextEpisodeToAir: TEpisodeToAir.fromJson(json["next_episode_to_air"] ?? <your-default-value>),
This will check your code for the value of json["next_episode_to_air"] and put an your default value at it's place if it turns out to be null. You can then deal with this default (or maybe null) value accordingly in your code later.
I have solved the issue with null case handling.In 2nd response, response with key next_episode_to_air is null. Due to this getting error, accessing key on null.
Just handle the possible case for data, currently at factory TVShow.fromJson i.e.
nextEpisodeToAir: json["next_episode_to_air"] == null ? null : TEpisodeToAir.fromJson(json["next_episode_to_air"])
I'm receiving an Error following the Json Deserialisation cookbook
NoSuchMethodError: Class '_InternalLinkedHashMap<String, dynamic>' has no instance method 'map' with matching arguments.
Bundle Class
class Bundle {
String resourceType;
String id;
String type;
int total;
List<Link> link;
List<Entry> entry;
Bundle(
{this.resourceType,
this.id,
this.type,
this.total,
this.link,
this.entry});
factory Bundle.fromJson(Map<String, dynamic> json) {
return Bundle(
resourceType : json['resourceType'],
id : json['id'],
type : json['type'],
total : json['total'],
);
}
Code:
try {
await parsePerson(resultString);
} catch (e) {
print('Bundlelist Error: $e');
}
Future<List<Bundle>> parsePerson(String body) async {
List<Bundle> bundleList = [];
try {
final parsed = json.decode(body);
bundleList = parsed.map<Bundle>((json) => Bundle.fromJson(json)).toList;
} catch (e) {
print('FutureError: $e');
}
return bundleList;
}
My Result string (partial): Full json is here.
{"resourceType":"Bundle","id":"f26779b4-5c3c-4c52-83b4-c689516a6a08","type":"searchset","link":[{"relation":"self","url":"https://fhir-open.sandboxcerner.com/dstu2/0b8a0111-e8e6-4c26-a91c-5069cbc6b1ca/Patient?name=b\u0026_count=20"},{"relation":"next","url":"https://fhir-open.sandboxcerner.com/dstu2/0b8a0111-e8e6-4c26-a91c-5069cbc6b1ca/Patient?-pageContext=7018d2bc-6be4-48e1-b8a4-a40f4e98c98c\u0026-pageDirection=NEXT"}],"entry":[{"fullUrl":"https://fhir-open.sandboxcerner.com/dstu2/0b8a0111-e8e6-4c26-a91c-5069cbc6b1ca/Patient/6160015","resource":{"resourceType":"Patient","id":"6160015","meta":{"versionId":"0","lastUpdated":"2019-07-08T20:37:03.000Z"},"text":{"status":"generated","div":"\u003Cdiv\u003E\u003Cp\u003E\u003Cb\u003EPatient\u003C/b\u003E\u003C/p\u003E\u003Cp\u003E\u003Cb\u003EName\u003C/b\u003E: 111d3fcaffb244b2b207c07ffa5a14, bf607a7f1f284e8aa3559d52249bc7\u003C/p\u003E\u003Cp\u003E\u003Cb\u003EDOB\u003C/b\u003E: Mar 15, 1936\u003C/p\u003E\u003Cp\u003E\u003Cb\u003EAdministrative Gend
I've tried various suggestions from here including:
final parsed = jsonDecode(body).cast<Map<String, dynamic>>();
Returns
NoSuchMethodError: Class '_InternalLinkedHashMap<String, dynamic>' has no instance method 'cast' with matching arguments.
I'm quite lost as to what to try next.
You need an array, but your response is a map
You json string is too long, I can not paste full code contains your full json
You can copy paste , replace yourjsonstring and run full code below
Your json string contains control character \n and need to replace before parse
You can get all related class in full code
code snippet
String jsonString = '''yourjsonstring''';
String replaced = jsonString.replaceAll('\n',r'\\n');
final payload = payloadFromJson(replaced);
print(payload.link[0].relation);
print(payload.link[0].url);
print(payload.entry[0].resource.address[0].text);
full code
import 'package:flutter/material.dart';
// To parse this JSON data, do
//
// final payload = payloadFromJson(jsonString);
import 'dart:convert';
Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));
String payloadToJson(Payload data) => json.encode(data.toJson());
class Payload {
String resourceType;
String id;
String type;
List<Link> link;
List<Entry> entry;
Payload({
this.resourceType,
this.id,
this.type,
this.link,
this.entry,
});
factory Payload.fromJson(Map<String, dynamic> json) => Payload(
resourceType: json["resourceType"],
id: json["id"],
type: json["type"],
link: List<Link>.from(json["link"].map((x) => Link.fromJson(x))),
entry: List<Entry>.from(json["entry"].map((x) => Entry.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"resourceType": resourceType,
"id": id,
"type": type,
"link": List<dynamic>.from(link.map((x) => x.toJson())),
"entry": List<dynamic>.from(entry.map((x) => x.toJson())),
};
}
class Entry {
String fullUrl;
Resource resource;
Entry({
this.fullUrl,
this.resource,
});
factory Entry.fromJson(Map<String, dynamic> json) => Entry(
fullUrl: json["fullUrl"],
resource: Resource.fromJson(json["resource"]),
);
Map<String, dynamic> toJson() => {
"fullUrl": fullUrl,
"resource": resource.toJson(),
};
}
class Resource {
ResourceType resourceType;
String id;
Meta meta;
TextClass text;
List<Identifier> identifier;
bool active;
List<Name> name;
List<Telecom> telecom;
Gender gender;
DateTime birthDate;
List<Address> address;
Resource({
this.resourceType,
this.id,
this.meta,
this.text,
this.identifier,
this.active,
this.name,
this.telecom,
this.gender,
this.birthDate,
this.address,
});
factory Resource.fromJson(Map<String, dynamic> json) => Resource(
resourceType: resourceTypeValues.map[json["resourceType"]],
id: json["id"],
meta: Meta.fromJson(json["meta"]),
text: TextClass.fromJson(json["text"]),
identifier: List<Identifier>.from(json["identifier"].map((x) => Identifier.fromJson(x))),
active: json["active"],
name: List<Name>.from(json["name"].map((x) => Name.fromJson(x))),
telecom: List<Telecom>.from(json["telecom"].map((x) => Telecom.fromJson(x))),
gender: genderValues.map[json["gender"]],
birthDate: DateTime.parse(json["birthDate"]),
address: List<Address>.from(json["address"].map((x) => Address.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"resourceType": resourceTypeValues.reverse[resourceType],
"id": id,
"meta": meta.toJson(),
"text": text.toJson(),
"identifier": List<dynamic>.from(identifier.map((x) => x.toJson())),
"active": active,
"name": List<dynamic>.from(name.map((x) => x.toJson())),
"telecom": List<dynamic>.from(telecom.map((x) => x.toJson())),
"gender": genderValues.reverse[gender],
"birthDate": "${birthDate.year.toString().padLeft(4, '0')}-${birthDate.month.toString().padLeft(2, '0')}-${birthDate.day.toString().padLeft(2, '0')}",
"address": List<dynamic>.from(address.map((x) => x.toJson())),
};
}
class Address {
AddressUse use;
String text;
List<String> line;
String city;
String state;
String postalCode;
String country;
AddressPeriod period;
Address({
this.use,
this.text,
this.line,
this.city,
this.state,
this.postalCode,
this.country,
this.period,
});
factory Address.fromJson(Map<String, dynamic> json) => Address(
use: addressUseValues.map[json["use"]],
text: json["text"],
line: List<String>.from(json["line"].map((x) => x)),
city: json["city"],
state: json["state"],
postalCode: json["postalCode"],
country: json["country"],
period: json["period"] == null ? null : AddressPeriod.fromJson(json["period"]),
);
Map<String, dynamic> toJson() => {
"use": addressUseValues.reverse[use],
"text": text,
"line": List<dynamic>.from(line.map((x) => x)),
"city": city,
"state": state,
"postalCode": postalCode,
"country": country,
"period": period == null ? null : period.toJson(),
};
}
class AddressPeriod {
DateTime start;
AddressPeriod({
this.start,
});
factory AddressPeriod.fromJson(Map<String, dynamic> json) => AddressPeriod(
start: DateTime.parse(json["start"]),
);
Map<String, dynamic> toJson() => {
"start": start.toIso8601String(),
};
}
enum AddressUse { HOME, WORK, MOBILE }
final addressUseValues = EnumValues({
"home": AddressUse.HOME,
"mobile": AddressUse.MOBILE,
"work": AddressUse.WORK
});
enum Gender { UNKNOWN, OTHER }
final genderValues = EnumValues({
"other": Gender.OTHER,
"unknown": Gender.UNKNOWN
});
class Identifier {
IdentifierUse use;
Type type;
IdentifierSystem system;
String identifierValue;
Value value;
AddressPeriod period;
Identifier({
this.use,
this.type,
this.system,
this.identifierValue,
this.value,
this.period,
});
factory Identifier.fromJson(Map<String, dynamic> json) => Identifier(
use: identifierUseValues.map[json["use"]],
type: Type.fromJson(json["type"]),
system: identifierSystemValues.map[json["system"]],
identifierValue: json["value"],
value: Value.fromJson(json["_value"]),
period: AddressPeriod.fromJson(json["period"]),
);
Map<String, dynamic> toJson() => {
"use": identifierUseValues.reverse[use],
"type": type.toJson(),
"system": identifierSystemValues.reverse[system],
"value": identifierValue,
"_value": value.toJson(),
"period": period.toJson(),
};
}
enum IdentifierSystem { URN_OID_2168401113883378700, URN_OID_111111, URN_OID_21684011138833421000110000112 }
final identifierSystemValues = EnumValues({
"urn:oid:1.1.1.1.1.1": IdentifierSystem.URN_OID_111111,
"urn:oid:2.16.840.1.113883.3.42.10001.100001.12": IdentifierSystem.URN_OID_21684011138833421000110000112,
"urn:oid:2.16.840.1.113883.3.787.0.0": IdentifierSystem.URN_OID_2168401113883378700
});
class Type {
List<Coding> coding;
TextEnum text;
Type({
this.coding,
this.text,
});
factory Type.fromJson(Map<String, dynamic> json) => Type(
coding: json["coding"] == null ? null : List<Coding>.from(json["coding"].map((x) => Coding.fromJson(x))),
text: textEnumValues.map[json["text"]],
);
Map<String, dynamic> toJson() => {
"coding": coding == null ? null : List<dynamic>.from(coding.map((x) => x.toJson())),
"text": textEnumValues.reverse[text],
};
}
class Coding {
String system;
Code code;
Display display;
bool userSelected;
Coding({
this.system,
this.code,
this.display,
this.userSelected,
});
factory Coding.fromJson(Map<String, dynamic> json) => Coding(
system: json["system"],
code: codeValues.map[json["code"]],
display: displayValues.map[json["display"]],
userSelected: json["userSelected"],
);
Map<String, dynamic> toJson() => {
"system": system,
"code": codeValues.reverse[code],
"display": displayValues.reverse[display],
"userSelected": userSelected,
};
}
enum Code { MR }
final codeValues = EnumValues({
"MR": Code.MR
});
enum Display { MEDICAL_RECORD_NUMBER }
final displayValues = EnumValues({
"Medical record number": Display.MEDICAL_RECORD_NUMBER
});
enum TextEnum { COMMUNITY_MEDICAL_RECORD_NUMBER, MRN, MILITARY_ID }
final textEnumValues = EnumValues({
"Community Medical Record Number": TextEnum.COMMUNITY_MEDICAL_RECORD_NUMBER,
"Military Id": TextEnum.MILITARY_ID,
"MRN": TextEnum.MRN
});
enum IdentifierUse { USUAL }
final identifierUseValues = EnumValues({
"usual": IdentifierUse.USUAL
});
class Value {
List<Extension> extension;
Value({
this.extension,
});
factory Value.fromJson(Map<String, dynamic> json) => Value(
extension: List<Extension>.from(json["extension"].map((x) => Extension.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"extension": List<dynamic>.from(extension.map((x) => x.toJson())),
};
}
class Extension {
String url;
String valueString;
Extension({
this.url,
this.valueString,
});
factory Extension.fromJson(Map<String, dynamic> json) => Extension(
url: json["url"],
valueString: json["valueString"],
);
Map<String, dynamic> toJson() => {
"url": url,
"valueString": valueString,
};
}
class Meta {
String versionId;
DateTime lastUpdated;
Meta({
this.versionId,
this.lastUpdated,
});
factory Meta.fromJson(Map<String, dynamic> json) => Meta(
versionId: json["versionId"],
lastUpdated: DateTime.parse(json["lastUpdated"]),
);
Map<String, dynamic> toJson() => {
"versionId": versionId,
"lastUpdated": lastUpdated.toIso8601String(),
};
}
class Name {
NameUse use;
String text;
List<String> family;
List<String> given;
List<String> prefix;
NamePeriod period;
List<String> suffix;
Name({
this.use,
this.text,
this.family,
this.given,
this.prefix,
this.period,
this.suffix,
});
factory Name.fromJson(Map<String, dynamic> json) => Name(
use: nameUseValues.map[json["use"]],
text: json["text"],
family: List<String>.from(json["family"].map((x) => x)),
given: List<String>.from(json["given"].map((x) => x)),
prefix: json["prefix"] == null ? null : List<String>.from(json["prefix"].map((x) => x)),
period: json["period"] == null ? null : NamePeriod.fromJson(json["period"]),
suffix: json["suffix"] == null ? null : List<String>.from(json["suffix"].map((x) => x)),
);
Map<String, dynamic> toJson() => {
"use": nameUseValues.reverse[use],
"text": text,
"family": List<dynamic>.from(family.map((x) => x)),
"given": List<dynamic>.from(given.map((x) => x)),
"prefix": prefix == null ? null : List<dynamic>.from(prefix.map((x) => x)),
"period": period == null ? null : period.toJson(),
"suffix": suffix == null ? null : List<dynamic>.from(suffix.map((x) => x)),
};
}
class NamePeriod {
DateTime start;
DateTime end;
NamePeriod({
this.start,
this.end,
});
factory NamePeriod.fromJson(Map<String, dynamic> json) => NamePeriod(
start: json["start"] == null ? null : DateTime.parse(json["start"]),
end: json["end"] == null ? null : DateTime.parse(json["end"]),
);
Map<String, dynamic> toJson() => {
"start": start == null ? null : start.toIso8601String(),
"end": end == null ? null : end.toIso8601String(),
};
}
enum NameUse { OFFICIAL, OLD }
final nameUseValues = EnumValues({
"official": NameUse.OFFICIAL,
"old": NameUse.OLD
});
enum ResourceType { PATIENT }
final resourceTypeValues = EnumValues({
"Patient": ResourceType.PATIENT
});
class Telecom {
TelecomSystem system;
ValueEnum value;
AddressUse use;
AddressPeriod period;
Telecom({
this.system,
this.value,
this.use,
this.period,
});
factory Telecom.fromJson(Map<String, dynamic> json) => Telecom(
system: telecomSystemValues.map[json["system"]],
value: valueEnumValues.map[json["value"]],
use: addressUseValues.map[json["use"]],
period: json["period"] == null ? null : AddressPeriod.fromJson(json["period"]),
);
Map<String, dynamic> toJson() => {
"system": telecomSystemValues.reverse[system],
"value": valueEnumValues.reverse[value],
"use": addressUseValues.reverse[use],
"period": period == null ? null : period.toJson(),
};
}
enum TelecomSystem { PHONE, EMAIL }
final telecomSystemValues = EnumValues({
"email": TelecomSystem.EMAIL,
"phone": TelecomSystem.PHONE
});
enum ValueEnum { THE_3213213213, NAME_FAKEMAIL_COM, THE_8888888888 }
final valueEnumValues = EnumValues({
"name#fakemail.com": ValueEnum.NAME_FAKEMAIL_COM,
"321-321-3213": ValueEnum.THE_3213213213,
"888-888-8888": ValueEnum.THE_8888888888
});
class TextClass {
Status status;
String div;
TextClass({
this.status,
this.div,
});
factory TextClass.fromJson(Map<String, dynamic> json) => TextClass(
status: statusValues.map[json["status"]],
div: json["div"],
);
Map<String, dynamic> toJson() => {
"status": statusValues.reverse[status],
"div": div,
};
}
enum Status { GENERATED }
final statusValues = EnumValues({
"generated": Status.GENERATED
});
class Link {
String relation;
String url;
Link({
this.relation,
this.url,
});
factory Link.fromJson(Map<String, dynamic> json) => Link(
relation: json["relation"],
url: json["url"],
);
Map<String, dynamic> toJson() => {
"relation": relation,
"url": url,
};
}
class EnumValues<T> {
Map<String, T> map;
Map<T, String> reverseMap;
EnumValues(this.map);
Map<T, String> get reverse {
if (reverseMap == null) {
reverseMap = map.map((k, v) => new MapEntry(v, k));
}
return reverseMap;
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
String jsonString = '''yourjsonstring''';
//String jsonString = '''{"newLine": "here is a \n newline \u003E \u0026 \u003C aaa"}''';
void _incrementCounter() {
String replaced = jsonString.replaceAll('\n',r'\\n');
final payload = payloadFromJson(replaced);
print(payload.link[0].relation);
print(payload.link[0].url);
print(payload.entry[0].resource.address[0].text);
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}