Why is my json code gives Instance of Post - json

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

Related

Flutter JSON to DataTable

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'),
)
],
),
),
),
);
}
}

Getting null instead of List of strings flutter json

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.

Flutter json Expected a value of type 'List<dynamic>', but got one of type ''

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());
}

Why can't i get data value from json - flutter

Am trying to get values from my json file categories.json using flutter but am always getting error or its not showing and I don't really know what is wrong
This is my main.dart
Future<List<Category>> loadData() async {
String jString = await rootBundle.loadString("assets/categories.json");
List<dynamic> jRes = jsonDecode(jString);
List<Category> datas = jRes.map((e) => Category.fromJson(e)).toList();
return datas;
}
Container(
child: FutureBuilder<List<Category>>(
future: loadData(),
builder: (context, data) {
if (data.connectionState != ConnectionState.waiting &&
data.hasData) {
var userList = data.data;
return ListView.builder(
itemCount: userList.length,
itemBuilder: (context, index) {
var userData = userList[index];
return Column(
children: [
Text("Category: ${userData.catName}"),
],
);
});
} else {
return Center(
child: CircularProgressIndicator(),
);
}
})),
and my model.dart
class Category {
String catId;
String catName;
SubCategory subcat;
Category({this.catId, this.catName, this.subcat});
factory Category.fromJson(Map<String, dynamic> json) {
return Category(
catId: json['cat_id'],
catName: json['category'],
subcat: SubCategory.fromJson(json['cat_subcategory']),
);
}
Map<String, dynamic> toJson() {
return {
"cat_id": catId,
"category": catName,
};
}
}
class SubCategory {
String subName, subImage;
SubCategory({this.subName, this.subImage});
factory SubCategory.fromJson(Map<String, dynamic> json) {
return SubCategory(subName: json['sub_name'], subImage: json['sub_image']);
}
Map<String, dynamic> toJson() {
return {
"sub_name": subName,
"sub_image": subImage,
};
}
}
and lastly my categories.json file
[{
"category": "Design & Creativity",
"cat_id": "1",
"cat_subcategory": [
{
"sub_name": "Ads",
"sub_image": "https://images.unsplash.com/photo-1589838017489-9198a27bd040?ixid=MXwxMjA3fDB8MHxzZWFyY2h8Mnx8YWR2ZXJ0aXNlbWVudHxlbnwwfHwwfA%3D%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60"
}
]
}]
//There are more of them
The problem am facing when I run it is that it only shows me the CircularProgressIndicator() in my main.dart and when I remove the if statement, it says Another exception was thrown: NoSuchMethodError: The getter 'length' was called on null. Please how do I go about solving this problem and if you need more explanation then tell me
PS: When I check the loadData() value it says type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'
EDIT: Thank you all for the answers but what i did was to generate a model using this website model generator
and i was able to get the value
Personally, when I want to load data from json file, I do this:
Future<List<Category>> loadData() async {
List<Category> datas = [];
return rootBundle.loadString("assets/categories.json").then((value) {
List<dynamic> jRes = jsonDecode(value);
jRes.forEach((element) {
datas.add(Category.fromJson(element));
});
return datas;
});
}
Also, in SubCategory class
factory SubCategory.fromJson(Map<String, dynamic> json) {
return SubCategory(subName: json['sub_name'], subImage: json['sub_image']);
}
Your fromJson() require Map<String, dynamic>.
But if you look at your file
"cat_subcategory": [
{
"sub_name": "Ads",
"sub_image": "https://images.unsplash.com/photo-1589838017489-9198a27bd040?ixid=MXwxMjA3fDB8MHxzZWFyY2h8Mnx8YWR2ZXJ0aXNlbWVudHxlbnwwfHwwfA%3D%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60"
}
]
You can see that cat_subcategory is a List
So you are giving a List to your SubCategory.fromJson() instead of a Map.
If you want to give a Map, you can simply give the first index of your list
Your Category.fromJson() become
factory Category.fromJson(Map<String, dynamic> json) {
return Category(
catId: json['cat_id'],
catName: json['category'],
subcat: SubCategory.fromJson(json['cat_subcategory'][0]),
);
}
Change your model.dart class
class Category {
String category;
String catId;
List<CatSubcategory> catSubcategory;
Category({this.category, this.catId, this.catSubcategory});
Category.fromJson(Map<String, dynamic> json) {
category = json['category'];
catId = json['cat_id'];
if (json['cat_subcategory'] != null) {
catSubcategory = new List<CatSubcategory>();
json['cat_subcategory'].forEach((v) {
catSubcategory.add(new CatSubcategory.fromJson(v));
});
}}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['category'] = this.category;
data['cat_id'] = this.catId;
if (this.catSubcategory != null) {
data['cat_subcategory'] =
this.catSubcategory.map((v) => v.toJson()).toList();
}
return data;
}}
class CatSubcategory {
String subName;
String subImage;
CatSubcategory({this.subName, this.subImage});
CatSubcategory.fromJson(Map<String, dynamic> json) {
subName = json['sub_name'];
subImage = json['sub_image'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['sub_name'] = this.subName;
data['sub_image'] = this.subImage;
return data;
}}
And Replace
List<Category> datas = jRes.map((e) => Category.fromJson(e)).toList();
with
List<Category> datas = List<Category>.from(jRes.map((category)=> Category.fromJson(category)));

Not getting required value from json list - flutter

I have this code where am able to get values from an online json data and print its value
main.dart
final String url = 'https://raw.githubusercontent.com/BrightCode1/ohms-json/master/categories.json';
List<JsonModel> myModel = [];
List<CatSubcategory> subCate = [];
int localInt;
#override
void initState() {
// TODO: implement initState
super.initState();
localInt = 0;
loadData(localInt);
}
loadData(int dataInt) async {
var res = await http.get(url, headers: {"Accept": "application/json"});
if (res.statusCode == 200) {
String resBody = res.body;
var jsonDecode = json.decode(resBody);
for (var data in jsonDecode) {
data['cat_subcategory'].map((x) {
return subCate.add(
CatSubcategory(subName: x['sub_name'], subImage: x['sub_image']));
}).toList();
myModel.add(JsonModel(
category: data['category'],
catId: data['cat_id'],
catIcon: data['cat_icon'],
catSubcategory: subCate));
setState(() {});
}
print(myModel[dataInt].catSubcategory.length);
} else {
print("Something went wrong!");
}
}
my model.dart
class JsonModel {
JsonModel({
this.category,
this.catId,
this.catIcon,
this.catSubcategory,
});
String category;
String catId;
String catIcon;
List<CatSubcategory> catSubcategory;
factory JsonModel.fromJson(Map<String, dynamic> json) => JsonModel(
category: json["category"],
catId: json["cat_id"],
catIcon: json["cat_icon"],
catSubcategory: List<CatSubcategory>.from(
json["cat_subcategory"].map((x) => CatSubcategory.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"category": category,
"cat_id": catId,
"cat_icon": catIcon,
"cat_subcategory":
List<dynamic>.from(catSubcategory.map((x) => x.toJson())),
};
}
class CatSubcategory {
CatSubcategory({
this.subName,
this.subImage,
});
String subName;
String subImage;
factory CatSubcategory.fromJson(Map<String, dynamic> json) => CatSubcategory(
subName: json["sub_name"],
subImage: json["sub_image"],
);
Map<String, dynamic> toJson() => {
"sub_name": subName,
"sub_image": subImage,
};
}
The only problem am having now is that when I try to print the length on the subcategory of the first list it gives me 24 instead of 6 and i printed it like this myModel[dataInt].catSubcategory.length. The dataInt is 0 which means it's supposed to print out the length of the children("cat_subcategory") with category of Design & Creativity but it's printing all the other children of the other lis. So please how do i go about this. And if you need more explanation tell me
I would avoid writing your own model from scratch if you already know the schema of your json.
Just use something like https://app.quicktype.io/ just paste your json and you will get
import 'dart:convert';
class Root {
Root({
this.category,
this.catId,
this.catIcon,
this.catSubcategory,
});
String category;
String catId;
String catIcon;
List<CatSubcategory> catSubcategory;
factory Root.fromJson(Map<String, dynamic> json) => Root(
category: json["category"],
catId: json["cat_id"],
catIcon: json["cat_icon"] == null ? null : json["cat_icon"],
catSubcategory: List<CatSubcategory>.from(json["cat_subcategory"].map((x) => CatSubcategory.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"category": category,
"cat_id": catId,
"cat_icon": catIcon == null ? null : catIcon,
"cat_subcategory": List<dynamic>.from(catSubcategory.map((x) => x.toJson())),
};
}
class CatSubcategory {
CatSubcategory({
this.subName,
this.subImage,
});
String subName;
String subImage;
factory CatSubcategory.fromJson(Map<String, dynamic> json) => CatSubcategory(
subName: json["sub_name"],
subImage: json["sub_image"],
);
Map<String, dynamic> toJson() => {
"sub_name": subName,
"sub_image": subImage,
};
}
and then you should be good to just
loadData(int dataInt) async {
var res = await http.get(url, headers: {"Accept": "application/json"});
if (res.statusCode == 200) {
String resBody = res.body;
var list = json.decode(resBody) as List;
List<Root> items = list.map((i)=>Root.fromJson(i)).toList();
print(items[0].catSubcategory.length);
}
} else {
print("Something went wrong!");
}
}
https://repl.it/talk/share/Sample/118111