OrderItem Model Class:
This is my OrderItem Model Class which contains a CartItem Map as I am trying to Parse this I am getting error "type 'List' is not a subtype of type 'Map<String, dynamic>'"
import 'package:flutter/cupertino.dart';
import 'package:practice_app/models/shippingAdress.dart';
import 'package:practice_app/providers/cart_provider.dart';
class OrderItem with ChangeNotifier {
final String? id;
final String? orderNo;
final DateTime? date;
final String? paymentMethod;
final ShippingAdress? shippingAdress;
final Map<String, CartItem>? cartItem;
final int? price;
OrderItem({
this.id,
this.orderNo,
this.date,
this.paymentMethod,
this.shippingAdress,
this.cartItem,
this.price,
});
factory OrderItem.fromJson(Map<String, dynamic> json) {
print('Json:');
print(json);
//tempitems
final json1 = json['order'];
Map<String, CartItem> dd = {};
final temp = CartItem.fromJson(json['order']) as Map<String, CartItem>;
final tempadd = ShippingAdress.fromJson(json['shippingAddress']) as ShippingAdress;
//final map = Map<String, CartItem>.from(temp);
print("printing temp items");
print(temp);
print("temp address");
//print(tempadd);
return OrderItem(
id: json['ProductID'].toString(),
orderNo: json['OrderNO'] ?? '',
date: json['Date'] ?? DateTime.now(),
paymentMethod: json['paymentMethod'] ?? 0,
shippingAdress: tempadd,
cartItem: temp,
price: json["price"] ?? '');
}
CartItem Model Class:
Here is the fromJson Method Define for CartItem.
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class CartItem {
String? id;
String? plantId;
String? title;
num? price;
int? quantity;
String? imageAssets;
String? size;
Color? color;
CartItem({
this.id,
this.plantId,
this.title,
this.price,
this.quantity,
this.imageAssets,
this.size,
this.color,
});
factory CartItem.fromJson(Map<String, dynamic> json) {
return CartItem(
id: json['id'] as String,
plantId: json['plantId'] as String,
title: json['title'] as String,
price: json['price'] as int,
quantity: json['quantity'] as int,
imageAssets: json['imageAsset'] as String,
size: json['size'] as String,
color: json['color'] ?? Colors.green[400] as Color,
);
}
Map toJson() => {
'id': this.id,
'plantId': this.plantId,
'title': this.title,
'price': this.price,
'quantity': this.quantity,
'imageAsset': this.imageAssets,
'size': this.size,
'color': this.color,
};
}
class Cart with ChangeNotifier {
Map<String, CartItem> _item = {};
Map<String, CartItem> get items {
return {..._item};
}
List<CartItem> get cartitem {
return [..._item.values.toList()];
}
int get itemCount {
return _item.length;
}
void emptyCart() {
_item.clear();
notifyListeners();
}
CartItem findById(String id) {
return _item.values.toList().firstWhere((element) => element.id == id);
}
double get totalAmount {
double total = 0.0;
_item.forEach((key, cartItem) {
total += cartItem.price! * cartItem.quantity!;
});
return total;
}
void removeItem(String productId) {
_item.remove(productId);
notifyListeners();
}
void updateCart(String id, CartItem newCart) {
// try {
if (_item.containsKey(id)) {
_item.update(
id,
(value) => CartItem(
plantId: newCart.plantId,
id: newCart.id,
title: newCart.title,
price: newCart.price,
quantity: newCart.quantity,
imageAssets: newCart.imageAssets,
size: newCart.size,
color: newCart.color,
),
);
}
notifyListeners();
// final SharedPreferences prefs = await SharedPreferences.getInstance();
// final cartData = json.encode(
// {
// _item,
// },
// );
// prefs.setString('CartData', cartData);
// } catch (error) {
// throw error;
// }
}
Future<void> addItem(String plantId, String quantity, String title,
double price, String image, String size, Color color) async {
int quantityy = quantity == '' ? 1 : int.parse(quantity);
String sizee = size == 'Small'
? 'Small'
: size == 'Large'
? 'Large'
: size == 'Extra Large'
? 'Extra Large'
: '';
try {
if (_item.containsKey(plantId)) {
//change Quantity
_item.update(
plantId,
(existingCartItem) => CartItem(
plantId: plantId,
id: existingCartItem.id,
title: existingCartItem.title,
price: existingCartItem.price,
imageAssets: existingCartItem.imageAssets,
quantity: existingCartItem.quantity! + quantityy,
size: sizee,
color: color,
),
);
} else {
_item.putIfAbsent(
plantId,
() => CartItem(
plantId: plantId,
id: DateTime.now().toString(),
title: title,
price: price,
imageAssets: image,
quantity: quantityy,
size: sizee,
color: color,
),
);
}
print(plantId);
notifyListeners();
final SharedPreferences prefs = await SharedPreferences.getInstance();
//print(${cartitem.first.});
final cartData = jsonEncode(
{
'cartItem': _item.toString(),
},
);
prefs.setString('CartData', cartData);
print(cartData);
print('Shared done');
} catch (error) {
throw error;
}
}
Future<bool> tryAutoFillCart() async {
final perfs = await SharedPreferences.getInstance();
if (!perfs.containsKey('CartData')) {
return false;
}
final fetchCartData = perfs.getString('CartData');
final extractedCartData =
jsonDecode(fetchCartData!) as Map<String, dynamic>;
_item = extractedCartData['cartItem'] as Map<String, CartItem>;
notifyListeners();
return true;
}
}
API DATA RESPONSE:
This is my Api data response I'm trying to parse specifically the order.
{
"StatusCode": 200,
"StatusMessage": "success",
"ProductID": 20,
"orderNO": 20,
"Date": null,
"paymentMethod": "Visa",
"shippingAddress": {
"ID": "20",
"FullName": "Ali",
"ShippingAddress": "Stadium Road"
},
"order": [
{
"id": "p8",
"plantId": "3",
"title": "Ali",
"imageAsset": "assets/images/plant3.png",
"price": 80,
"size": "Small",
"color": null,
"quantity": 4
},
{
"id": "p8",
"plantId": "3",
"title": "IQBAL",
"imageAsset": "assets/images/plant2.png",
"price": 80,
"size": "Small",
"color": null,
"quantity": 4
}
],
"price": 1500,
"Message": null
}
Error
Error I am getting trying to parse
Related
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);
}
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 map response to model class and then show all elements one by one, so that user can scroll down. Response goes like that:
{"items":[{"id":"bd9acd37-5c91-47cb-a71e-0e43fb2f7882","imageUrl":"","title":"fak hez as","city":"Gdansk"},{"id":"210ad8c8-d279-4c38-845c-34c772cfec21","imageUrl":"","title":"Some random title :)","city":"Warsaw"}],"total":2,"pageNumber":1}
And my model which I have generated with https://plugins.jetbrains.com/plugin/12562-jsontodart-json-to-dart-
class Advertisement {
List<Items>? _items;
int? _total;
int? _pageNumber;
List<Items>? get items => _items;
int? get total => _total;
int? get pageNumber => _pageNumber;
Advertisement({List<Items>? items, int? total, int? pageNumber}) {
_items = items;
_total = total;
_pageNumber = pageNumber;
}
Advertisement.fromJson(dynamic json) {
if (json["items"] != null) {
_items = [];
json["items"].forEach((v) {
_items?.add(Items.fromJson(v));
});
}
_total = json["total"];
_pageNumber = json["pageNumber"];
}
Map<String, dynamic> toJson() {
var map = <String, dynamic>{};
if (_items != null) {
map["items"] = _items?.map((v) => v.toJson()).toList();
}
map["total"] = _total;
map["pageNumber"] = _pageNumber;
return map;
}
}
/// id : "bd9acd37-5c91-47cb-a71e-0e43fb2f7882"
/// imageUrl : ""
/// title : "fak hez as"
/// city : "Gdansk"
class Items {
String? _id;
String? _imageUrl;
String? _title;
String? _city;
String? get id => _id;
String? get imageUrl => _imageUrl;
String? get title => _title;
String? get city => _city;
Items({String? id, String? imageUrl, String? title, String? city}) {
_id = id;
_imageUrl = imageUrl;
_title = title;
_city = city;
}
Items.fromJson(dynamic json) {
_id = json["id"];
_imageUrl = json["imageUrl"];
_title = json["title"];
_city = json["city"];
}
Map<String, dynamic> toJson() {
var map = <String, dynamic>{};
map["id"] = _id;
map["imageUrl"] = _imageUrl;
map["title"] = _title;
map["city"] = _city;
return map;
}
}
My screen:
import 'dart:convert';
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:.../constants/AppConstants.dart';
import 'package:.../ui/pages/home/page/Advertisement.dart';
import 'package:.../util/HttpActions.dart';
import 'BottomAppBar.dart';
import 'FAB.dart';
import 'Advertisement.dart';
class HomePage extends StatefulWidget {
final String jwt;
const HomePage(this.jwt);
#override
_HomePage createState() => _HomePage();
factory HomePage.fromBase64(String jwt) => HomePage(jwt);
}
class _HomePage extends State<HomePage> {
late final String jwt;
#override
void initState() {
super.initState();
jwt = widget.jwt;
}
#override
Widget build(BuildContext context) => Scaffold(
body: Scaffold(
backgroundColor: const Color(0xFEF9F9FC),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked,
floatingActionButton: buildFAB(),
bottomNavigationBar: BuildBottomAppBar(),
body: Container(
padding: EdgeInsets.all(35.0),
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Column(
children: [
FutureBuilder(
future: fetchAdvertisements(),
builder: (context, snapshot) => snapshot.hasData
? Text("")
: snapshot.hasError
? Text("An error occurred")
: CircularProgressIndicator(),
),
],
),
),
),
);
Future<List<Advertisement>?> fetchAdvertisements() async {
var response = await HttpActions.makeHttpGet(
{},
AppConstants.ADVERTISEMENTS_ENDPOINT,
{HttpHeaders.contentTypeHeader: HttpActions.APPLICATION_JSON_HEADER});
print(response.statusCode);
if (response.statusCode == 200) {
print(response.body);
final responseList = json.decode(response.body);
print(responseList);
List<Advertisement> z = (json.decode(response.body) as List)
.map((i) => Advertisement.fromJson(i))
.toList();
print(z);
return null;
} else {
throw Exception('Failed to load post');
}
}
}
Error occurs while executing this line:
List<Advertisement> z = (json.decode(response.body) as List)
.map((i) => Advertisement.fromJson(i))
.toList();
it does not map to this List
While debugging I get:
What I'm making wrong? Is there something wrong with model class?
One more mistake that you are making with your code, You are calling fetchAdvertisement() method inside a build(BuildContext context). This means everytime build() method gets called. It will call fetchAdvertisement() this as well.
Column(
children: [
FutureBuilder(
future: fetchAdvertisements(),
builder: (context, snapshot) => snapshot.hasData
? Text("")
: snapshot.hasError
? Text("An error occurred")
: CircularProgressIndicator(),
),
],
),
To avoid such an issue.
late Function _fetchAdvertisements;
void initState() {
super.initState();
_fetchAdvertisements = fetchAdvertisements(); }
Column(
children: [
FutureBuilder(
future: _fetchAdvertisements,
builder: (context, snapshot) => snapshot.hasData
? Text("")
: snapshot.hasError
? Text("An error occurred")
: CircularProgressIndicator(),
),
],
),
You cannot simply parse this with cast as List. Because your response isn't even a List.
{
"items": [
{
"id": "bd9acd37-5c91-47cb-a71e-0e43fb2f7882",
"imageUrl": "",
"title": "fak hez as",
"city": "Gdansk"
},
{
"id": "210ad8c8-d279-4c38-845c-34c772cfec21",
"imageUrl": "",
"title": "Pozdrawiam z Łodzi :)",
"city": "Warsaw"
}
],
"total": 2,
"pageNumber": 1
}
For this response, you can parse this like this:
Advertisement.fromJson(json.decode(response.body))
But now you have only one item of Advertisement.
If your response were like this, with multiple advertisements:
{
"advertisements": [
{
"items": [
{
"id": "bd9acd37-5c91-47cb-a71e-0e43fb2f7882",
"imageUrl": "",
"title": "fak hez as",
"city": "Gdansk"
},
{
"id": "212ad8c8-d279-4c38-845c-34c772cfec21",
"imageUrl": "",
"title": "Great city!",
"city": "Łódź"
}
],
"total": 2,
"pageNumber": 1
},
{
"items": [
{
"id": "bd9acd37-5c91-47cb-a71e-0e43fb2f7882",
"imageUrl": "",
"title": "fak hez as",
"city": "Gdansk"
},
{
"id": "210ad8c8-d279-4c38-845c-34c772cfec21",
"imageUrl": "",
"title": "Some random title :)",
"city": "Warsaw"
}
],
"total": 2,
"pageNumber": 1
}
]
}
You can parse this simply with this code:
List<Advertisement> advertisements = [
for (final advertisement in json.decode(response2)['advertisements'])
Advertisement.fromJson(advertisement)
];
You can learn how to do JSON serialization properly with JsonSerializable I recommend you to read this here.
I just copied you responded.body text and showed you a dummy example. Everything will be done in the same way, weather you use an HTTP calls. Always make sure that you know what response is coming.
class __AppState extends State<_App> {
#override
void initState() {
// TODO: implement initState
super.initState();
convertApiResponse();
}
Future<String> getApiJson() async {
return '{"items":[{"id":"bd9acd37-5c91-47cb-a71e-0e43fb2f7882","imageUrl":"","title":"fak hez as","city":"Gdansk"},{"id":"210ad8c8-d279-4c38-845c-34c772cfec21","imageUrl":"","title":"Some random title :)","city":"Warsaw"}],"total":2,"pageNumber":1} ';
}
Future<void> convertApiResponse() async {
final data = await getApiJson();
final decodedData = json.decode(data) as Map;
Advertisement x = Advertisement.fromJson(decodedData);
x._items!.forEach((element) {
log("Item-> City: ${element.city}");
log("Item->ID: ${element.id}");
log("Item->ImageURL: ${element.imageUrl}");
log("Item->Title: ${element.title}");
});
log("Page Number: ${x.pageNumber}");
log("Total: ${x.total}");
}
#override
Widget build(BuildContext context) {
return MaterialApp(home: Scaffold());
}
}
Untouched Items.dart
class Items {
String? _id;
String? _imageUrl;
String? _title;
String? _city;
String? get id => _id;
String? get imageUrl => _imageUrl;
String? get title => _title;
String? get city => _city;
Items({String? id, String? imageUrl, String? title, String? city}) {
_id = id;
_imageUrl = imageUrl;
_title = title;
_city = city;
}
Items.fromJson(dynamic json) {
_id = json["id"];
_imageUrl = json["imageUrl"];
_title = json["title"];
_city = json["city"];
}
Map<String, dynamic> toJson() {
var map = <String, dynamic>{};
map["id"] = _id;
map["imageUrl"] = _imageUrl;
map["title"] = _title;
map["city"] = _city;
return map;
}
}
Untouched Advertisement.dart
class Advertisement {
List<Items>? _items;
int? _total;
int? _pageNumber;
List<Items>? get items => _items;
int? get total => _total;
int? get pageNumber => _pageNumber;
Advertisement({List<Items>? items, int? total, int? pageNumber}) {
_items = items;
_total = total;
_pageNumber = pageNumber;
}
Advertisement.fromJson(dynamic json) {
if (json["items"] != null) {
_items = [];
json["items"].forEach((v) {
_items?.add(Items.fromJson(v));
});
}
_total = json["total"];
_pageNumber = json["pageNumber"];
}
Map<String, dynamic> toJson() {
var map = <String, dynamic>{};
if (_items != null) {
map["items"] = _items?.map((v) => v.toJson()).toList();
}
map["total"] = _total;
map["pageNumber"] = _pageNumber;
return map;
}
}
Here is a picture that resolves your fetchAdvertisements() call on every build
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),
),
);
}
}
I'm using Dio to get a request from this Api: Api Example
The response is like:
{
"count": 87,
"next": "https://swapi.co/api/people/?page=2",
"previous": null,
"results": [
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"hair_color": "blond",
"skin_color": "fair",
"eye_color": "blue",
"birth_year": "19BBY",
"gender": "male",
"homeworld": "https://swapi.co/api/planets/1/",
"films": [
"https://swapi.co/api/films/2/",
"https://swapi.co/api/films/6/",
"https://swapi.co/api/films/3/",
"https://swapi.co/api/films/1/",
"https://swapi.co/api/films/7/"
],
"species": [
"https://swapi.co/api/species/1/"
],
"vehicles": [
"https://swapi.co/api/vehicles/14/",
"https://swapi.co/api/vehicles/30/"
],
"starships": [
"https://swapi.co/api/starships/12/",
"https://swapi.co/api/starships/22/"
],
"created": "2014-12-09T13:50:51.644000Z",
"edited": "2014-12-20T21:17:56.891000Z",
"url": "https://swapi.co/api/people/1/"
},
And I have this code in dart:
void _getNames() async {
final response = await dio.get('https://swapi.co/api/people');
List tempList = new List();
for (int i = 0; i < response.data['results'].length; i++) {
tempList.add(response.data['results'][i]);
}
setState(() {
names = tempList;
names.shuffle();
filteredNames = names;
});
}
With this code, i only get the name of the results but i don't know how to get the other fields, i've tried some things but nothing works. I know that it would be very easy but i don't know how to do.
Here you go
_getPeople() async {
var response = await http.get('https://swapi.co/api/people/');
if (response != null && response.statusCode == 200) {
ResultModel jsonResponse =
ResultModel.fromJson(convert.jsonDecode(response.body));
print(jsonResponse);
}
}
ResultModel code is
class ResultModel {
int count;
String next;
dynamic previous;
List<Result> results;
ResultModel({
this.count,
this.next,
this.previous,
this.results,
});
factory ResultModel.fromJson(Map<String, dynamic> json) {
return ResultModel(
count: json['count'],
next: json['next'],
previous: json['previous'],
results: _parseResult(json['results']),
);
}
}
_parseResult(List<dynamic> data) {
List<Result> results = new List<Result>();
data.forEach((item) {
results.add(Result.fromJson(item));
});
return results;
}
_parseString(List<dynamic> data) {
List<String> results = new List<String>();
data.forEach((item) {
results.add(item);
});
return results;
}
class Result {
String name;
String height;
String mass;
String hairColor;
String skinColor;
String eyeColor;
String birthYear;
String gender;
String homeworld;
List<String> films;
List<String> species;
List<String> vehicles;
List<String> starships;
String created;
String edited;
String url;
Result({
this.name,
this.height,
this.mass,
this.hairColor,
this.skinColor,
this.eyeColor,
this.birthYear,
this.gender,
this.homeworld,
this.films,
this.species,
this.vehicles,
this.starships,
this.created,
this.edited,
this.url,
});
factory Result.fromJson(Map<String, dynamic> json) {
return Result(
name: json['name'],
height: json['height'],
mass: json['mass'],
hairColor: json['hairColor'],
skinColor: json['skinColor'],
eyeColor: json['eyeColor'],
birthYear: json['birthYear'],
gender: json['gender'],
homeworld: json['homeworld'],
films: _parseString(json['films']),
species: _parseString(json['species']),
vehicles: _parseString(json['vehicles']),
created: json['created'],
edited: json['edited'],
url: json['url'],
);
}
}