Would you be able to help me a bit as I am struggling with a conversion of API response into JSON/Object and then into DataTable.
I have a Stateful widget where I am getting data during Init:
class _AlertState extends State<Alert> {
final Api _api_service = Api();
late Future<List<Data>> _watchdog;
#override
void initState() {
_watchdog = _api_service.get_watchdog();
super.initState();
}
get_watchdog()
Future<List<Data>> get_watchdog() async {
var data = utf8.encode('{xxx}');
Response raw_response = await post(url, headers: headers, body: data);
if (raw_response.statusCode == 200) {
var res_json = jsonDecode(raw_response.body);
Watchdog watchdog = Watchdog.fromJson(res_json);
return watchdog.result!.data!;
} else{
Api.error_message = raw_response.statusCode as String;
throw Exception('xxx');
}
}
Watchdog object
class Watchdog {
String? version;
Error? error;
Result? result;
Watchdog({this.version, this.error, this.result});
Watchdog.fromJson(Map<String, dynamic> json) {
version = json['version'];
result = json['error'] != null ? new Result.fromJson(json['error']) : null;
result = json['result'] != null ? new Result.fromJson(json['result']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['version'] = this.version;
if (this.result != null) {
data['result'] = this.result!.toJson();
}
if (this.error != null) {
data['error'] = this.result!.toJson();
}
return data;
}
}
class Result {
String? now;
List<Data>? data;
Result({this.now, this.data});
Result.fromJson(Map<String, dynamic> json) {
now = json['now'];
if (json['data'] != null) {
data = <Data>[];
json['data'].forEach((v) {
data!.add(new Data.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['now'] = this.now;
if (this.data != null) {
data['data'] = this.data!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Data {
String? status;
String? problemtype;
String? message;
Data({this.status, this.problemtype, this.message});
Data.fromJson(Map<String, dynamic> json) {
status = json['status'];
problemtype = json['problemtype'];
message = json['message'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['status'] = this.status;
data['problemtype'] = this.problemtype;
data['message'] = this.message;
return data;
}
#override
String toString() {
return "Data(status: $status, problemtype: $problemtype, message: $message)";
}
}
class Error {
int? code;
String? message;
String? name;
Error({this.code, this.message, this.name});
Error.fromJson(Map<String, dynamic> json) {
code = json['code'];
message = json['message'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['code'] = this.code;
data['message'] = this.message;
data['name'] = this.name;
return data;
}
}
Can you please point me how to convert now the returned Future into Datatable when I press the button?
Widget build(BuildContext context) {
return Column(
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columns: <DataColumn>[
DataColumn(
label: Text('Status'),
),
DataColumn(
label: Text('Description'),
),
],
// rows: ???
),
),
TextButton(
onPressed: () {
if (_watchdog != null){
_watchdog.
} else{
print('empty');
}
},
child: Text('print'),
)
],
);
}
Thanks.
Can you please point me how to convert now the returned Future into Datatable when I press the button
=>you want to get data from API after clicking on the button, right ?
Solution ^^
In this case , you can't use a FutureBuilder Widget. Therefore ,include the last code in the stateful widget then you may simply use setState
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List<Data>? _watchdogs; // ---> remove Future
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Center(
child: Column(
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Visibility(
visible: _watchdogs!=null,
child: DataTable(
columns: <DataColumn>[
DataColumn(
label: Text('Status'),
),
DataColumn(
label: Text('Description'),
),
], rows: _watchdogs!.map((_watchdog) =>
DataRow(cells: [
//example
DataCell(Text(${_watchdog.name})),
DataCell(Text(${_watchdog.type})),
])
).toList(),
),
)
),
ElevatedButton(
onPressed: () async{
if (_watchdogs != null){
//get data from API, not forget to add async and await here
List<Data> data =await _api_service.get_watchdog();
setState(() {
_watchdogs=data;
});
} else{
print('empty');
}
},
child: Text('print'),
)
],
),
),
),
);
}
}
Related
Hello guys i have a small project with flutter. Try to list meals from https://www.themealdb.com/. I wish to list the meals in api. So far so good but the main problem some of the food listed some of are not.
For example Beef category not listening and give me this error:
[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: type
'Null' is not a subtype of type 'String'
but vegan category is listening.
screen Page :
class _MealScreenState extends State<MealScreen> {
List<Meal> mealsIn = [];
Future<bool> getMealInside() async {
Uri uri = Uri.parse(
'https://www.themealdb.com/api/json/v1/1/search.php?s=${widget.names}');
final response = await http.get(uri);
if (response.statusCode == 200) {
final result = mealsJsonFromJson(response.body);
mealsIn = result.meals;
setState(() {});
return true;
} else {
return false;
}
}
#override
void initState() {
super.initState();
getMealInside();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.names),
),
body: ListView.separated(
itemBuilder: (context, index) {
final mealsOut = mealsIn[index];
return ListTile(
title: Text(mealsOut.strMeal != null
? mealsOut.strMeal.toString()
: 'Loading'),
leading: Image.network(mealsOut.strMealThumb),
);
},
separatorBuilder: (context, index) => Divider(),
itemCount: mealsIn.length
),
);
}
}
model page:
import 'dart:convert';
MealData mealDataFromJson(String str) => MealData.fromJson(json.decode(str));
String mealDataToJson(MealData data) => json.encode(data.toJson());
class MealData {
MealData({
required this.categories,
});
List<Category> categories;
factory MealData.fromJson(Map<String, dynamic> json) => MealData(
categories: List<Category>.from(json["categories"].map((x) => Category.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"categories": List<dynamic>.from(categories.map((x) => x.toJson())),
};
class Category {
Category({
required this.idCategory,
required this.strCategory,
required this.strCategoryThumb,
required this.strCategoryDescription,
});
String idCategory;
String strCategory;
String strCategoryThumb;
String strCategoryDescription;
factory Category.fromJson(Map<String, dynamic> json) => Category(
idCategory: json["idCategory"],
strCategory: json["strCategory"],
strCategoryThumb: json["strCategoryThumb"],
strCategoryDescription: json["strCategoryDescription"],
);
Map<String, dynamic> toJson() => {
"idCategory": idCategory,
"strCategory": strCategory,
"strCategoryThumb": strCategoryThumb,
"strCategoryDescription": strCategoryDescription,
};
}
Beef
Vegan
You have to add null check for each keys : for Category class
factory Category.fromJson(Map<String, dynamic> json) => Category(
idCategory: json["idCategory"] ?? "",
strCategory: json["strCategory"] ?? "",
strCategoryThumb: json["strCategoryThumb"] ?? "",
strCategoryDescription: json["strCategoryDescription"] ?? "",
);
I'm making a recipes app that request the data form edamam Api and shows it in a listview.builder i have home screen class that make the request and shows the data
import 'package:flutter/material.dart';
import 'package:flutter_application_1/info_screen.dart';
import 'package:flutter_application_1/recipes.dart';
import 'dart:convert' as cnv;
import 'package:http/http.dart' as http;
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
_HomeScreen createState() => _HomeScreen();
}
class _HomeScreen extends State<HomeScreen> {
//List<MissedIngredients>? missedIngredients;
List<Recipe>? results;
int path = 0;
int? numberOfIngredants;
int numberOfRequestedRecipes = 3;
String? foodName;
#override
void initState() {
// TODO: implement initState
super.initState();
getData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Food recipe api'),
),
body: results == null
? Center(
child: CircularProgressIndicator(),
)
: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Card(
child: ListTile(
title: Text(results![index].label.toString()),
leading: Image.network(results![index].image.toString()),
onTap: () {
setState(() {
foodName = results![index].label.toString();
print(foodName);
});
},
));
},
itemCount: numberOfRequestedRecipes),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add_circle),
onPressed: () {
numberOfRequestedRecipes = numberOfRequestedRecipes + 10;
setState(() {
getData();
});
},
),
);
}
Future<void> getData() async {
http.Response res = await http.get(Uri.parse(
'https://api.edamam.com/api/recipes/v2?type=public&q=pizza&app_id=4dd9eafd&app_key=f2fa2c38ec16944f522dc9b734424cf4'));
print(res.body);
List<dynamic> body = cnv.jsonDecode(res.body)['hits'];
results = body.map((dynamic item) => Recipe.fromJson(item)).toList();
setState(() {});
}
}
and a recipes class that analyze the data so i can show it in the home screen
class recipes {
int ?from;
int ?to;
int ?count;
Links ?lLinks;
List<Hits> ?hits;
recipes({this.from, this.to, this.count, this.lLinks, this.hits});
recipes.fromJson(Map<String, dynamic> json) {
from = json['from'];
to = json['to'];
count = json['count'];
lLinks = json['_links'] != null ? new Links.fromJson(json['_links']) : null;
if (json['hits'] != null) {
hits = <Hits>[];
json['hits'].forEach((v) {
hits!.add(new Hits.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['from'] = this.from;
data['to'] = this.to;
data['count'] = this.count;
if (this.lLinks != null) {
data['_links'] = this.lLinks!.toJson();
}
if (this.hits != null) {
data['hits'] = this.hits!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Links {
Next ? next;
Links({required this.next});
Links.fromJson(Map<String, dynamic> json) {
next = (json['next'] != null ? new Next.fromJson(json['next']) : null)!;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.next != null) {
data['next'] = this.next!.toJson();
}
return data;
}
}
class Next {
String ?href;
String ?title;
Next({this.href, this.title});
Next.fromJson(Map<String, dynamic> json) {
href = json['href'];
title = json['title'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['href'] = this.href;
data['title'] = this.title;
return data;
}
}
class Hits {
Recipe ? recipe;
Links ? lLinks;
Hits({this.recipe, this.lLinks});
Hits.fromJson(Map<String, dynamic> json) {
recipe =
json['recipe'] != null ? new Recipe.fromJson(json['recipe']) : null;
lLinks = json['_links'] != null ? new Links.fromJson(json['_links']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.recipe != null) {
data['recipe'] = this.recipe!.toJson();
}
if (this.lLinks != null) {
data['_links'] = this.lLinks!.toJson();
}
return data;
}
}
class Recipe {
String ?uri;
String ?label;
String ?image;
String ?source;
String ?url;
String ?shareAs;
int ?yield;
Recipe(
{this.uri,
this.label,
this.image,
this.source,
this.url,
this.shareAs,
this.yield,
});
Recipe.fromJson(Map<String, dynamic> json) {
uri = json['uri'];
label = json['label'];
image = json['image'];
source = json['source'];
url = json['url'];
shareAs = json['shareAs'];
yield = json['yield'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['uri'] = this.uri;
data['label'] = this.label;
data['image'] = this.image;
data['source'] = this.source;
data['url'] = this.url;
data['shareAs'] = this.shareAs;
data['yield'] = this.yield;
return data;
}
}
class Ingredients {
String? text;
double? weight;
String? foodCategory;
String? foodId;
String? image;
Ingredients(
{this.text, this.weight, this.foodCategory, this.foodId, this.image});
Ingredients.fromJson(Map<String, dynamic> json) {
text = json['text'];
weight = json['weight'];
foodCategory = json['foodCategory'];
foodId = json['foodId'];
image = json['image'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['text'] = this.text;
data['weight'] = this.weight;
data['foodCategory'] = this.foodCategory;
data['foodId'] = this.foodId;
data['image'] = this.image;
return data;
}
}
but when I run the app all I get is a null value so what is the problem
thank you for your valuable time!
Hi the Simplest Solution for your problem is to use a FutureBuilder
If you use the Widget build,
the method will run simultaneous with the init method,due to which you might receive null values even when values are in process of fetching . So use a future builder of type bool and use only when there's data !=null.
Hi i am making a recipes app that shows the name of the food and the image of it and the ingredants
so i made simple home page that makes the requst and a class that gives me the data i used this url from spooncular.com :
https://api.spoonacular.com/recipes/complexSearch?apiKey=8fe91444f092411fa6011b71fd6e582d&number=1&query=pizza&fillIngredients=true
this the main class
import 'package:flutter/material.dart';
import 'package:flutter_application_1/recipes.dart';
import 'dart:convert' as cnv;
import 'package:http/http.dart' as http;
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
_HomeScreen createState() => _HomeScreen();
}
class _HomeScreen extends State<HomeScreen> {
List<MissedIngredients>? modell;
#override
void initState() {
// TODO: implement initState
super.initState();
getData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Food recipe api'),
),
body: modell == null
? Center(
child: CircularProgressIndicator(),
)
: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Card(
child: ExpansionTile(
title: Text(modell![index].originalName.toString()),
children: [
Text(modell![index].name.toString()),
Container(
child:
Image.network('modell![index].image.toString()'),
)
],
),
);
},
itemCount: modell!.length),
);
}
Future<void> getData() async {
http.Response res = await http.get(Uri.parse('https://api.spoonacular.com/recipes/complexSearch?apiKey=8fe91444f092411fa6011b71fd6e582d&number=1&query=pizza&fillIngredients=true'));
print(res.body);
List<dynamic> body = cnv.jsonDecode(res.body)['missedIngredients'];
modell = body.map((dynamic item) => MissedIngredients.fromJson(item)).toList();
setState(() {});
}
}
this is the recipes class i mdae it with json to dart class website
class recipes {
List<Results> ?results;
int? offset;
int? number;
int? totalResults;
recipes({this.results, this.offset, this.number, this.totalResults});
recipes.fromJson(Map<String, dynamic> json) {
if (json['results'] != null) {
results = <Results>[];
json['results'].forEach((v) {
results!.add(new Results.fromJson(v));
});
}
offset = json['offset'];
number = json['number'];
totalResults = json['totalResults'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.results != null) {
data['results'] = this.results!.map((v) => v.toJson()).toList();
}
data['offset'] = this.offset;
data['number'] = this.number;
data['totalResults'] = this.totalResults;
return data;
}
}
class Results {
int? id;
int? usedIngredientCount;
int? missedIngredientCount;
List<MissedIngredients> ?missedIngredients;
int ?likes;
List<Null>? usedIngredients;
List<Null>? unusedIngredients;
String ?title;
String ?image;
String ?imageType;
Results(
{this.id,
this.usedIngredientCount,
this.missedIngredientCount,
this.missedIngredients,
this.likes,
this.usedIngredients,
this.unusedIngredients,
this.title,
this.image,
this.imageType});
Results.fromJson(Map<String, dynamic> json) {
id = json['id'];
usedIngredientCount = json['usedIngredientCount'];
missedIngredientCount = json['missedIngredientCount'];
if (json['missedIngredients'] != null) {
missedIngredients = <MissedIngredients>[];
json['missedIngredients'].forEach((v) {
missedIngredients!.add(new MissedIngredients.fromJson(v));
});
}
title = json['title'];
image = json['image'];
imageType = json['imageType'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['usedIngredientCount'] = this.usedIngredientCount;
data['missedIngredientCount'] = this.missedIngredientCount;
if (this.missedIngredients != null) {
data['missedIngredients'] =
this.missedIngredients!.map((v) => v.toJson()).toList();
}
data['likes'] = this.likes;
data['title'] = this.title;
data['image'] = this.image;
data['imageType'] = this.imageType;
return data;
}
}
class MissedIngredients {
int ? id;
double? amount;
String ?unit;
String ?unitLong;
String ?unitShort;
String? aisle;
String? name;
String? original;
String? originalString;
String? originalName;
List<String> ?metaInformation;
List<String>? meta;
String ?image;
String? extendedName;
MissedIngredients(
{this.id,
this.amount,
this.unit,
this.unitLong,
this.unitShort,
this.aisle,
this.name,
this.original,
this.originalString,
this.originalName,
this.metaInformation,
this.meta,
this.image,
this.extendedName});
MissedIngredients.fromJson(Map<String, dynamic> json) {
id = json['id'];
amount = json['amount'];
unit = json['unit'];
unitLong = json['unitLong'];
unitShort = json['unitShort'];
aisle = json['aisle'];
name = json['name'];
original = json['original'];
originalString = json['originalString'];
originalName = json['originalName'];
metaInformation = json['metaInformation'].cast<String>();
meta = json['meta'].cast<String>();
image = json['image'];
extendedName = json['extendedName'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['amount'] = this.amount;
data['unit'] = this.unit;
data['unitLong'] = this.unitLong;
data['unitShort'] = this.unitShort;
data['aisle'] = this.aisle;
data['name'] = this.name;
data['original'] = this.original;
data['originalString'] = this.originalString;
data['originalName'] = this.originalName;
data['metaInformation'] = this.metaInformation;
data['meta'] = this.meta;
data['image'] = this.image;
data['extendedName'] = this.extendedName;
return data;
}
}
Note:when i try to use the Results class like the title or the image it works but when i try to use missedingredants class it gives me this error Expected a value of type 'List', but got one of type 'Null'
if you want any further info please ask me I the comments and thank you!
Use below method in your case,
Future<void> getData() async {
http.Response res = await http.get(Uri.parse('https://api.spoonacular.com/recipes/complexSearch?apiKey=8fe91444f092411fa6011b71fd6e582d&number=1&query=pizza&fillIngredients=true'));
print(res.body);
var jsonData = cnv.jsonDecode(res.body);
modell = jsonData['results'][0]['missedIngredients'].map((dynamic item) => MissedIngredients.fromJson(item)).toList();
setState(() {});
}
And when there is multiple data in your "results" list you can find "missedIngredients" list into resultList Array,
Future<void> getData() async {
http.Response res = await http.get(Uri.parse('https://api.spoonacular.com/recipes/complexSearch?apiKey=8fe91444f092411fa6011b71fd6e582d&number=1&query=pizza&fillIngredients=true'));
print(res.body);
var jsonData = cnv.jsonDecode(res.body);
List<Results> resultList = jsonData['results'].map(
(jsonElement) => Results.fromJson(jsonElement)
).toList();
print(resultList[0].missedIngredients.length.toString());
}
I am trying to fetch data from internet. And this is the json string:
{"channel":{"id":1090161,"name":"İscaklik","description":"İscakliği okeyrum da.","latitude":"0.0","longitude":"0.0","field1":"nem","field2":"iscaklik","created_at":"2020-06-27T11:56:47Z","updated_at":"2020-06-27T11:56:47Z","last_entry_id":1},"feeds":[{"created_at":"2020-06-27T12:02:32Z","entry_id":1,"field1":"5"}]}
I want to get the "field1" in "feeds".
And my code is like that:
class _DataState extends State<Data> {
Future<String> AlbumState;
void initState() {
super.initState();
oku();
}
var a;
Future<List<Post>> oku() async {
final response = await http.get(
'https://api.thingspeak.com/channels/1090161/fields/1.json?api_key=JD9JYHAT2YHOI5Q3&results=1');
if (response.statusCode == 200) {
var responseJson = json.decode(response.body);
return (responseJson['feeds'] as List)
.map((p) => Post.fromJson(p))
.toList();
} else {
throw Exception('La bulamadık la böyle bi şey yoh la');
}
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: Center(
child: FutureBuilder<List<Post>>(
future: oku(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.toString());
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
),
),
),
);
}
}
class Post {
final String field1;
Post({this.field1});
factory Post.fromJson(Map<String, dynamic> json) {
return new Post(
field1: json['entry_id'].toString(),
);
}
}
This is the result:
I want to see the 5.(Which is the field1 of feeds)
Why I am seeing this?
How can I fix this?
Because you trying to use the entire object like the String in the Text widget. Try to call the attribute field1 you have in the Post class.
return Text(snapshot.data[0].field1);
Just Copy And Paste this model class and the simple use
if (response.statusCode == 200) {
var responseJson = json.decode(response.body);
ModelChannel channel = ModelChannel.fromJson(responseJson);
return channel.feeds;
} else {
throw Exception('La bulamadık la böyle bi şey yoh la');
}
Here is your JSON model
class ModelChannel {
Channel channel;
List<Feed> feeds;
ModelChannel({this.channel, this.feeds});
factory ModelChannel.fromJson(Map<String, dynamic> json) {
return ModelChannel(
channel: json['channel'] != null ? Channel.fromJson(json['channel']) : null,
feeds: json['feeds'] != null ? (json['feeds'] as List).map((i) => Feed.fromJson(i)).toList() : null,
);
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.channel != null) {
data['channel'] = this.channel.toJson();
}
if (this.feeds != null) {
data['feeds'] = this.feeds.map((v) => v.toJson()).toList();
}
return data;
}
}
class Feed {
String created_at;
int entry_id;
String field1;
Feed({this.created_at, this.entry_id, this.field1});
factory Feed.fromJson(Map<String, dynamic> json) {
return Feed(
created_at: json['created_at'],
entry_id: json['entry_id'],
field1: json['field1'],
);
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['created_at'] = this.created_at;
data['entry_id'] = this.entry_id;
data['field1'] = this.field1;
return data;
}
}
class Channel {
String created_at;
String description;
String field1;
String field2;
int id;
int last_entry_id;
String latitude;
String longitude;
String name;
String updated_at;
Channel({this.created_at, this.description, this.field1, this.field2, this.id, this.last_entry_id, this.latitude, this.longitude, this.name, this.updated_at});
factory Channel.fromJson(Map<String, dynamic> json) {
return Channel(
created_at: json['created_at'],
description: json['description'],
field1: json['field1'],
field2: json['field2'],
id: json['id'],
last_entry_id: json['last_entry_id'],
latitude: json['latitude'],
longitude: json['longitude'],
name: json['name'],
updated_at: json['updated_at'],
);
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['created_at'] = this.created_at;
data['description'] = this.description;
data['field1'] = this.field1;
data['field2'] = this.field2;
data['id'] = this.id;
data['last_entry_id'] = this.last_entry_id;
data['latitude'] = this.latitude;
data['longitude'] = this.longitude;
data['name'] = this.name;
data['updated_at'] = this.updated_at;
return data;
}
}
You may refer to this code, You should call the attribute data.feeds[0].field1-
function ItemListCtrl($scope, $http) {
$http.get("https://api.thingspeak.com/channels/1090161/fields/1.json?api_key=JD9JYHAT2YHOI5Q3&results=1", {
headers: {
'Content-Type': 'application/json'
}
}).success(function(data) {
console.log(data.feeds[0].field1)
$scope.data = angular.fromJson(data.feeds[0].field1);
});
}
Fiddle
Dart / Flutter JSON parsing and display
I am having trouble parsing and displaying the info. Am getting data from API
I get a response == 200 from API but am unable to display it.
The printout on screen is "Instance of medData"
Future<medData> fetchData(http.Client client) async {
final response = await http.get(
'xxxxxxxxxx',
headers: {
"host": "rapidapi.com",
"key": "x87439756734",
},
);
if (response.statusCode == 200) {
// List json = json.decode(response.body);
// return json.map((medData) => new medData.fromJson(medData)).toList();
return medData.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load data from API');
}
}
This Is the List View Builder
ListView _medDataListView(data) {
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return _tile(data[index].cases, data[index].number, Icons.work);
});
}
Tile builder
ListTile _tile(String title, String subtitle, IconData icon) => ListTile(
title: Text(title,
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 20,
)),
subtitle: Text(subtitle),
leading: Icon(
icon,
color: Colors.blue[500],
),
);
Class medData for parsing the JSON
class medData {
String country;
List<LatestStatByCountry> latestStatByCountry;
medData({this.country, this.latestStatByCountry});
medData.fromJson(Map<String, dynamic> json) {
country = json['country'];
if (json['latest_stat_by_country'] != null) {
latestStatByCountry = new List<LatestStatByCountry>();
json['latest_stat_by_country'].forEach((v) {
latestStatByCountry.add(new LatestStatByCountry.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['country'] = this.country;
if (this.latestStatByCountry != null) {
data['latest_stat_by_country'] =
this.latestStatByCountry.map((v) => v.toJson()).toList();
}
return data;
}
}
class LatestStatByCountry {
String id;
String countryName;
String totalCases;
String newCases;
String activeCases;
String totalDeaths;
String newDeaths;
String totalRecovered;
String seriousCritical;
Null region;
String totalCasesPer1m;
String recordDate;
LatestStatByCountry(
{this.id,
this.countryName,
this.totalCases,
this.newCases,
this.activeCases,
this.totalDeaths,
this.newDeaths,
this.totalRecovered,
this.seriousCritical,
this.region,
this.totalCasesPer1m,
this.recordDate});
LatestStatByCountry.fromJson(Map<String, dynamic> json) {
id = json['id'];
countryName = json['country_name'];
totalCases = json['total_cases'];
newCases = json['new_cases'];
activeCases = json['active_cases'];
totalDeaths = json['total_deaths'];
newDeaths = json['new_deaths'];
totalRecovered = json['total_recovered'];
seriousCritical = json['serious_critical'];
region = json['region'];
totalCasesPer1m = json['total_cases_per1m'];
recordDate = json['record_date'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['country_name'] = this.countryName;
data['total_cases'] = this.totalCases;
data['new_cases'] = this.newCases;
data['active_cases'] = this.activeCases;
data['total_deaths'] = this.totalDeaths;
data['new_deaths'] = this.newDeaths;
data['total_recovered'] = this.totalRecovered;
data['serious_critical'] = this.seriousCritical;
data['region'] = this.region;
data['total_cases_per1m'] = this.totalCasesPer1m;
data['record_date'] = this.recordDate;
return data;
}
}
Building the widget
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FutureBuilder<medData>(
future: fetchData(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text("${snapshot.data}");
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
),
),
);
}
}
I don't really know what i'm doing wrong when trying to display the data.
You can copy paste run full code below
Step 1 : parse json string with medDataFromJson(response.body);
factory MedData.fromJson(Map<String, dynamic> json) => MedData(
country: json["country"],
latestStatByCountry: List<LatestStatByCountry>.from(
json["latest_stat_by_country"]
.map((x) => LatestStatByCountry.fromJson(x))),
);
Step 2 : In FutureBuilder do return _medDataListView(snapshot.data.latestStatByCountry);
Step 3: ListView _medDataListView(List<LatestStatByCountry> data) data is List<LatestStatByCountry>
working demo
full code
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
// To parse this JSON data, do
//
// final medData = medDataFromJson(jsonString);
import 'dart:convert';
MedData medDataFromJson(String str) => MedData.fromJson(json.decode(str));
String medDataToJson(MedData data) => json.encode(data.toJson());
class MedData {
String country;
List<LatestStatByCountry> latestStatByCountry;
MedData({
this.country,
this.latestStatByCountry,
});
factory MedData.fromJson(Map<String, dynamic> json) => MedData(
country: json["country"],
latestStatByCountry: List<LatestStatByCountry>.from(
json["latest_stat_by_country"]
.map((x) => LatestStatByCountry.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"country": country,
"latest_stat_by_country":
List<dynamic>.from(latestStatByCountry.map((x) => x.toJson())),
};
}
class LatestStatByCountry {
String id;
String countryName;
String totalCases;
String newCases;
String activeCases;
String totalDeaths;
String newDeaths;
String totalRecovered;
String seriousCritical;
dynamic region;
String totalCasesPer1M;
DateTime recordDate;
LatestStatByCountry({
this.id,
this.countryName,
this.totalCases,
this.newCases,
this.activeCases,
this.totalDeaths,
this.newDeaths,
this.totalRecovered,
this.seriousCritical,
this.region,
this.totalCasesPer1M,
this.recordDate,
});
factory LatestStatByCountry.fromJson(Map<String, dynamic> json) =>
LatestStatByCountry(
id: json["id"],
countryName: json["country_name"],
totalCases: json["total_cases"],
newCases: json["new_cases"],
activeCases: json["active_cases"],
totalDeaths: json["total_deaths"],
newDeaths: json["new_deaths"],
totalRecovered: json["total_recovered"],
seriousCritical: json["serious_critical"],
region: json["region"],
totalCasesPer1M: json["total_cases_per1m"],
recordDate: DateTime.parse(json["record_date"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"country_name": countryName,
"total_cases": totalCases,
"new_cases": newCases,
"active_cases": activeCases,
"total_deaths": totalDeaths,
"new_deaths": newDeaths,
"total_recovered": totalRecovered,
"serious_critical": seriousCritical,
"region": region,
"total_cases_per1m": totalCasesPer1M,
"record_date": recordDate.toIso8601String(),
};
}
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'),
);
}
}
MedData medData;
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;
void _incrementCounter() {
setState(() {
_counter++;
});
}
ListView _medDataListView(List<LatestStatByCountry> data) {
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return _tile(
data[index].countryName, data[index].totalCases, Icons.work);
});
}
ListTile _tile(String title, String subtitle, IconData icon) => ListTile(
title: Text(title,
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 20,
)),
subtitle: Text(subtitle),
leading: Icon(
icon,
color: Colors.blue[500],
),
);
Future<MedData> fetchData(http.Client client) async {
final response = await http.get(
'https://coronavirus-monitor.p.rapidapi.com/coronavirus/latest_stat_by_country.php?country=South%20Africa',
headers: {
"x-rapidapi-host": "coronavirus-monitor.p.rapidapi.com",
"x-rapidapi-key": "23bdb74dbfmsh865510b645e32f6p1f7b7bjsn2e800c1ac844",
},
);
/*String jsonString = '''
{ "country": "South Africa", "latest_stat_by_country": [ { "id": "216413", "country_name": "South Africa", "total_cases": "709", "new_cases": "", "active_cases": "697", "total_deaths": "", "new_deaths": "", "total_recovered": "12", "serious_critical": "2", "region": null, "total_cases_per1m": "12", "record_date": "2020-03-26 05:50:02.171" } ] }
''';
http.Response response = http.Response(jsonString, 200);*/
if (response.statusCode == 200) {
// List json = json.decode(response.body);
// return json.map((medData) => new medData.fromJson(medData)).toList();
//return medData.fromJson(json.decode(response.body));
medData = medDataFromJson(response.body);
return medData;
} else {
throw Exception('Failed to load data from API');
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FutureBuilder<MedData>(
future: fetchData(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasData) {
//return Text("${snapshot.data}");
return _medDataListView(snapshot.data.latestStatByCountry);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
),
),
);
}
}