How to get value from Instance of JSON in Flutter? - json

My current JSON file is in this format:
{
"feed":{
"entry":[
{
"id":{
"$t":"somedata"
},
"title":{
"type":"text",
"$t":"Stack Smash"
},
"content":{
"type":"text",
"$t":"somedata"
},
},
{
"id":{
"$t":"somedata"
},
"title":{
"type":"text",
"$t":"Stack Smash"
},
"content":{
"type":"text",
"$t":"somedata"
},
}
]
}
}
I need to parse json['feed']['entry'] and the contents within that (id, title, content).
This is my current implementation:
Future<List<Feed>> getData() async {
List<Feed> list;
String link = '$url';
var res = await http.get(link);
if (res.statusCode == 200) {
var data = json.decode(res.body);
var rest = data["feed"]["entry"] as List;
list = rest.map<Feed>((json) => Feed.fromJson(json)).toList();
}
return list;
}
}
class Feed {
ImageJSON image;
Feed({this.image});
factory Feed.fromJson(Map<String, dynamic> json) {
return Feed(
image: ImageJSON.fromJson(json["title"]));
}
}
class ImageJSON {
String image;
ImageJSON({this.image});
factory ImageJSON.fromJson(Map<String, dynamic> json) {
return ImageJSON(
image: json["\$t"] as String,
);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: gameAppBar(),
body: FutureBuilder(
future: getData(),
builder: (context, snapshot) {
return snapshot.data != null
? CustomScrollView(slivers: <Widget>[
SliverPadding(
padding: const EdgeInsets.only(
top: 20.0, left: 8, right: 8),
sliver: gamesGrid(snapshot.data)) ])
: Container(child: Text(snapshot.error));
}));
}
Widget gamesGrid(List<Feed> feed) {
return SliverPadding(
padding: const EdgeInsets.only(left: 8, right: 8),
sliver: SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
childAspectRatio: 2 / 2.9),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int i) {
return Column(
children: [
GridTile(
child: Image.network(
'${feed[i].image}',
fit: BoxFit.cover,
),
),
],
);
},
childCount: 100,
),
),
);
}
The code prints Instance of ImageJSON, how do I get my String from the ImageJSON?

GridTile(
child: Image.network(
'${feed[i].image.image}',
fit: BoxFit.cover,
),
),

Related

How can I get data from a local json file and create a gridview in Flutter?

I'm trying to make an educational application in Turkish and i want to list the topics on my homepage. I created a sketch of my homepage and i want to print the texts inside the cards by taking the parts named "konuBasligi" from the local json file.
Before sharing the codes, I would like to share the existing design and json file with you:
{
"bende": {
"dersler": [{
"id": 0,
"dersAdi": "Türkçe"
}, {
"id": 1,
"dersAdi": "Matematik"
}, {
"id": 2,
"dersAdi": "Tarih",
"konular": [{
"konuId": 0,
"konuBasligi": "İslamiyet Öncesi Türk Tarihi",
"altkonular": [{
"altKonuId": 0,
"altKonuBasligi": "Giriş",
"basliklar": [{
"baslikId": 0,
"baslikAdi": "Türk Adının Anlamı"
}, {
"baslikId": 1,
"baslikAdi": "İlk Yerleşim Yerleri"
}, {
"baslikId": 2,
"baslikAdi": "Göçler"
}]
}, {
"altKonuId": 1,
"altKonuBasligi": "İlk Türk Toplulukları ve Devletleri",
"basliklar": [{
"baslikId": 0,
"baslikAdi": "İskitler"
}, {
"baslikId": 1,
"baslikAdi": "Asya Hun Devleti"
}, {
"baslikId": 2,
"baslikAdi": "Avrupa Hun Devleti"
}]
}, {
"altKonuId": 2,
"altKonuBasligi": "Diğer Türk Toplulukları ve Devletleri",
"basliklar": [{
"baslikId": 0,
"baslikAdi": "Avatarlar"
}, {
"baslikId": 1,
"baslikAdi": "Karluklar"
}, {
"baslikId": 2,
"baslikAdi": "Kırgızlar"
}]
}, {
"altKonuId": 3,
"altKonuBasligi": "Kültür ve Medeniyet",
"basliklar": [{
"baslikId": 0,
"baslikAdi": "Hükümdarlar"
}, {
"baslikId": 1,
"baslikAdi": "Devlet Yönetimi"
}, {
"baslikId": 2,
"baslikAdi": "Ordu"
}]
}]
}, {
"konuId": 1,
"konuBasligi": "İlk Türk İslam Devletleri"
}, {
"konuId": 2,
"konuBasligi": "Türkiye Tarihi"
}, {
"konuId": 3,
"konuBasligi": "Osmanlı Tarihi"
}, {
"konuId": 4,
"konuBasligi": "Kurtuluş Savaşı"
}, {
"konuId": 5,
"konuBasligi": "Çağdaş Türk ve Dünya Tarihi"
}]
}, {
"id": 3,
"dersAdi": "Coğrafya"
}, {
"id": 4,
"dersAdi": "Vatandaşlık"
}, {
"id": 5,
"dersAdi": "Genel Kültür"
}, {
"id": 6,
"dersAdi": "Program Geliştirme"
}, {
"id": 7,
"dersAdi": "Rehberlik ve Özel Eğitim"
}, {
"id": 8,
"dersAdi": "Öğretim Yöntem ve Teknikleri"
}, {
"id": 9,
"dersAdi": "Ölçme ve Değerlendirme"
}, {
"id": 10,
"dersAdi": "Öğrenme Psikolojisi"
}, {
"id": 11,
"dersAdi": "Gelişim Psikolojisi"
}]
}
}
I think I read the data using "FutureBuilder" and "DefaultAssetBundle" from the video I watched and the articles I read, but I got stuck in the "children" part in "Gridview.count". I couldn't adapt it myself because they usually use "Listview.builder".
The code of the design image I shared contains too many files such as "screens", "utils". For this, I created a file with only the parts related to my question and its contents are as follows:
import 'dart:convert';
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Test',
home: Scaffold(
appBar: AppBar(
title: const Text('Gridview From JSON'),
),
body: FutureBuilder(
future: DefaultAssetBundle.of(context).loadString('data/veri.json'),
builder: (context, snapshot) {
var read = json.decode(snapshot.data.toString());
return GridView.count(
crossAxisCount: 2,
padding:
const EdgeInsets.only(left: 12.0, right: 12.0, top: 8.0),
scrollDirection: Axis.vertical,
childAspectRatio: 1,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16)),
clipBehavior: Clip.antiAlias,
color: Colors.blue[200],
),
],
);
}),
),
);
}
}
Thank you in advance for your help...
I Just spent some time on your question to recreate the example.
Step1: You need to convert the JSON to a model, which Can be done with the help of https://app.quicktype.io/ and save it as model.dart
// model.dart
// To parse this JSON data, do
//
// final reportData = reportDataFromJson(jsonString);
import 'dart:convert';
import 'package:flutter/material.dart';
ReportData reportDataFromJson(String str) =>
ReportData.fromJson(json.decode(str));
String reportDataToJson(ReportData data) => json.encode(data.toJson());
class ReportData {
ReportData({
this.bende,
});
Bende? bende;
factory ReportData.fromJson(Map<String, dynamic> json) => ReportData(
bende: Bende.fromJson(json["bende"]),
);
Map<String, dynamic> toJson() => {
"bende": bende!.toJson(),
};
}
class Bende {
Bende({
this.dersler,
});
List<Dersler>? dersler;
factory Bende.fromJson(Map<String, dynamic> json) => Bende(
dersler:
List<Dersler>.from(json["dersler"].map((x) => Dersler.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"dersler": List<dynamic>.from(dersler!.map((x) => x.toJson())),
};
}
class Dersler {
Dersler({
this.id,
this.dersAdi,
this.konular,
});
int? id;
String? dersAdi;
List<Konular>? konular;
factory Dersler.fromJson(Map<String, dynamic> json) => Dersler(
id: json["id"],
dersAdi: json["dersAdi"],
konular: json["konular"] == null
? null
: List<Konular>.from(
json["konular"].map((x) => Konular.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"id": id,
"dersAdi": dersAdi,
"konular": konular == null
? null
: List<dynamic>.from(konular!.map((x) => x.toJson())),
};
}
class Konular {
Konular({
this.konuId,
this.konuBasligi,
this.altkonular,
});
int? konuId;
String? konuBasligi;
List<Altkonular>? altkonular;
factory Konular.fromJson(Map<String, dynamic> json) => Konular(
konuId: json["konuId"],
konuBasligi: json["konuBasligi"],
altkonular: json["altkonular"] == null
? null
: List<Altkonular>.from(
json["altkonular"].map((x) => Altkonular.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"konuId": konuId,
"konuBasligi": konuBasligi,
"altkonular": altkonular == null
? null
: List<dynamic>.from(altkonular!.map((x) => x.toJson())),
};
}
class Altkonular {
Altkonular({
this.altKonuId,
this.altKonuBasligi,
this.basliklar,
});
int? altKonuId;
String? altKonuBasligi;
List<Basliklar>? basliklar;
factory Altkonular.fromJson(Map<String, dynamic> json) => Altkonular(
altKonuId: json["altKonuId"],
altKonuBasligi: json["altKonuBasligi"],
basliklar: List<Basliklar>.from(
json["basliklar"].map((x) => Basliklar.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"altKonuId": altKonuId,
"altKonuBasligi": altKonuBasligi,
"basliklar": List<dynamic>.from(basliklar!.map((x) => x.toJson())),
};
}
class Basliklar {
Basliklar({
this.baslikId,
this.baslikAdi,
});
int? baslikId;
String? baslikAdi;
factory Basliklar.fromJson(Map<String, dynamic> json) => Basliklar(
baslikId: json["baslikId"],
baslikAdi: json["baslikAdi"],
);
Map<String, dynamic> toJson() => {
"baslikId": baslikId,
"baslikAdi": baslikAdi,
};
}
Step2: Create a class to get Data from the model, something like
class DataFromReport {
static Future<ReportData> getDataLocally(BuildContext context) async {
final assetBundle = DefaultAssetBundle.of(context);
final data = await assetBundle.loadString('data/veri.json');
final reportData = reportDataFromJson(data);
return reportData;
}
}
Step3: Create a method to get the list of "konuBasligi" from ReportData
//getting list of konular from ReportData
List<String> getkonular(ReportData? data) {
List<String> listkonular = [];
//konular is not present in all dersler
// so fist get the length of dersler
int length = data?.bende?.dersler?.length ?? 0;
for (var i = 0; i < length; i++) {
final ders = data?.bende?.dersler?.elementAt(i);
//now get the number of konular
int length2 = ders?.konular?.length ?? 0;
for (var j = 0; j < length2; j++) {
final konu = ders?.konular?.elementAt(j);
listkonular.add(konu?.konuBasligi ?? '');
// print(konu?.konuBasligi);
}
}
return listkonular;
}
Step4: Finally display the items in GridView using FutureBuilder<ReportData>
FutureBuilder<ReportData>(
future: DataFromReport.getDataLocally(context),
builder: (context, snapshot) {
final data = snapshot.data;
final List<String> list = getkonular(data);
return GridView.count(
crossAxisCount: 2,
padding: const EdgeInsets.only(
left: 12.0, right: 12.0, top: 8.0),
scrollDirection: Axis.vertical,
childAspectRatio: 1,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
children: List.generate(list.length, (index) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16)),
clipBehavior: Clip.antiAlias,
color: Colors.blue[200],
child: Center(
child: Text(list[index],
style: const TextStyle(
fontSize: 20,
color: Colors.white,
))));
}));
}),
SnapShot of the Example:
main.dart full code.
import 'package:flutter/material.dart';
import 'package:get_local_json_data/model.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Test',
home: Scaffold(
appBar: AppBar(
title: const Text('Gridview From JSON'),
),
body: FutureBuilder<ReportData>(
future: DataFromReport.getDataLocally(context),
builder: (context, snapshot) {
final data = snapshot.data;
final List<String> list = getkonular(data);
return GridView.count(
crossAxisCount: 2,
padding: const EdgeInsets.only(
left: 12.0, right: 12.0, top: 8.0),
scrollDirection: Axis.vertical,
childAspectRatio: 1,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
children: List.generate(list.length, (index) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16)),
clipBehavior: Clip.antiAlias,
color: Colors.blue[200],
child: Center(
child: Text(list[index],
style: const TextStyle(
fontSize: 20,
color: Colors.white,
))));
}));
}),
));
}
}
//getting list of konular from ReportData
List<String> getkonular(ReportData? data) {
List<String> listkonular = [];
//konular is not present in all dersler
// so fist get the length of dersler
int length = data?.bende?.dersler?.length ?? 0;
for (var i = 0; i < length; i++) {
final ders = data?.bende?.dersler?.elementAt(i);
//now get the number of konular
int length2 = ders?.konular?.length ?? 0;
for (var j = 0; j < length2; j++) {
final konu = ders?.konular?.elementAt(j);
listkonular.add(konu?.konuBasligi ?? '');
// print(konu?.konuBasligi);
}
}
return listkonular;
}
class DataFromReport {
static Future<ReportData> getDataLocally(BuildContext context) async {
final assetBundle = DefaultAssetBundle.of(context);
final data = await assetBundle.loadString('data/veri.json');
final reportData = reportDataFromJson(data);
return reportData;
}
}
Folder Structure
Hope this will be helpful for you.
Actually you have to check for state before trying to use data in future builder. Try these -
FutureBuilder(
future: DefaultAssetBundle.of(context).loadString('data/veri.json'),
builder: (ctx, snapshot) {
// Checking if future is resolved
if (snapshot.connectionState == ConnectionState.done) {
// If we got an error
if (snapshot.hasError) {
return Center(
child: Text(
'${snapshot.error} occured',
style: TextStyle(fontSize: 18),
),
);
// if we got our data
} else if (snapshot.hasData) {
// Extracting data from snapshot object
var read = json.decode(snapshot.data.toString());
return GridView.count(
crossAxisCount: 2,
padding:
const EdgeInsets.only(left: 12.0, right: 12.0, top: 8.0),
scrollDirection: Axis.vertical,
childAspectRatio: 1,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16)),
clipBehavior: Clip.antiAlias,
color: Colors.blue[200],
),
],
);
}
}
),
Hope it helps.
You have two options:
First Option: is to continue using GridView.count() and for the children you have to just iterate on them in any method, maybe for loop or .map() method.
Let's say you will display the dersler read from the JSON file and you have created a variable to point on them like the following:
var read = json.decode(snapshot.data.toString());
final List dersler = read['dersler'];
Now you can generate the children by iterating over the data,
Example using .map() method:
children: dersler.map((item) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16)),
clipBehavior: Clip.antiAlias,
color: Colors.blue[200],
);
}).toList(),
Example using for loop:
children: [
for (int i = 0; i < dersler.length; i++)
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16)),
clipBehavior: Clip.antiAlias,
color: Colors.blue[200],
)
],
Second Option (Suggested): is to use GridView.builder() instead of using GridView.count() which gives you a bonus of lazy-loading the data into memory, which means only the data that is currently visible on the screen would be held in the memory, which is a very good optimization made out of the box by Flutter.
Example:
FutureBuilder(
future: DefaultAssetBundle.of(context).loadString('data/veri.json'),
builder: (context, snapshot) {
var read = json.decode(snapshot.data.toString());
final List dersler = read['dersler'];
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
padding: const EdgeInsets.only(left: 12.0, right: 12.0, top: 8.0),
scrollDirection: Axis.vertical,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: dersler.length,
itemBuilder: (BuildContext context, int index) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16)),
clipBehavior: Clip.antiAlias,
color: Colors.blue[200],
);
},
);
},
),

ReorderableSliverList with Futurebuilder

I'm trying to populate a ReorderableSliverList with data from an API using FutureBuilder.
Model (RouteOrderTable)
RouteOrderTable(
{required this.deliveryPeriod,
required this.driverId,
required this.processId,
required this.routeId,
required this.routeLines,
required this.status,
required this.vanId});
RouteOrderTable.fromJson(Map<String, dynamic> json) {
deliveryPeriod = json['deliveryPeriod'];
driverId = json['driverId'];
processId = json['processId'];
routeId = json['routeId'];
if (json['routeLines'] != null) {
routeLines = <RouteOrderLine>[];
json['routeLines'].forEach((v) {
routeLines!.add(new RouteOrderLine.fromJson(v));
});
}
status = json['status'];
vanId = json['vanId'];
}
Model (RouteOrderLine)
RouteOrderLine(
{required this.city,
required this.custAccount,
required this.custName,
required this.invoiceId,
required this.deliveryDate,
required this.productType,
required this.routeId,
required this.salesId,
required this.volume,
required this.weight});
RouteOrderLine.fromJson(Map<String, dynamic> json) {
city = json['city'];
custAccount = json['custAccount'];
custName = json['custName'];
deliveryDate = DateTime.tryParse(json['deliveryDate']);
invoiceId = json['invoiceId'];
productType = json['productType'];
routeId = json['routeId'];
salesId = json['salesId'];
volume = json['volume'];
weight = json['weight'];
}
JSON Data
[
{
"deliveryPeriod": 1,
"driverId": "",
"processId": "PRO000475",
"routeId": "ROU001804",
"routeLines": [
{
"city": "Naxxar",
"custAccount": "CUST010917",
"custName": "",
"deliveryDate": "2021-07-06T12:00:00",
"invoiceId": "",
"productType": 0,
"routeId": "ROU001804",
"salesId": "SO002496",
"volume": 0.011113889,
"weight": 8.700435
}
],
"status": 10,
"vanId": "TFI 943"
},
{
"deliveryPeriod": 2,
"driverId": "",
"processId": "PRO000475",
"routeId": "ROU001805",
"routeLines": [
{
"city": "Birkirkara",
"custAccount": "CUST010916",
"custName": "",
"deliveryDate": "2021-07-06T12:00:00",
"invoiceId": "",
"productType": 0,
"routeId": "ROU001805",
"salesId": "SO002497",
"volume": 0.005556111,
"weight": 4.349565
}
],
"status": 30,
"vanId": "HBA 804"
}
]
Screen - One of the issues here is that I cannot use removeAt() and insert() for the onReorder() because they aren't defined for the type Future.
class _SliverScreenState extends State<SliverScreenState> {
late Future<List<RouteOrderTable>> futureRouteTable;
#override
void initState() {
super.initState();
futureRouteTable = fetchData();
}
#override
Widget build(BuildContext context) {
void _onReorder(int oldIndex, int newIndex) {
/* setState(() {
Widget row = futureRouteTable!.removeAt(oldIndex);
futureRouteTable.insert(newIndex, row);
});*/
}
ScrollController _scrollController =
PrimaryScrollController.of(context) ?? ScrollController();
final someOtherSliver = SliverToBoxAdapter();
return FutureBuilder<List<RouteOrderTable>>(
future: futureRouteTable,
builder: (context, snapshot) {
Widget routeOrderListSliver;
final List<RouteOrderTable>? posts = snapshot.data;
if (snapshot.hasData) {
routeOrderListSliver = CustomScrollView(
controller: _scrollController,
slivers: <Widget>[
SliverAppBar(
flexibleSpace: FlexibleSpaceBar(
title: Text('ROUTE NO'),
),
),
ReorderableSliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(
title: Text(posts![index].routeId.toString(),
style: TextStyle(fontSize: 20.0),),
),
childCount: posts!.length,
),
onReorder: _onReorder,
),
],
);
}else {
routeOrderListSliver = Center(child: SliverToBoxAdapter(child: CircularProgressIndicator(),));
}
return CustomScrollView(
slivers: <Widget>[
someOtherSliver,
routeOrderListSliver
],
);
},
);
}
}
FetchData
Future<List<RouteOrderTable>> fetchData() async {
final response =
await http.get(Uri.parse('https://10.0.2.2:7038/api/route/1?siteId=1'));
try {
if (response.statusCode == 200) {
List<RouteOrderTable> lstRouteOrderTable = [];
Iterable l = jsonDecode(response.body);
lstRouteOrderTable = List<RouteOrderTable>.from(l.map((model) => RouteOrderTable.fromJson(model)));
return lstRouteOrderTable;
} else {
throw Exception('Failed to load route');
}
} catch (e) {
print(e);
}
return new List<RouteOrderTable>.empty();
}
ListView.builder
ListView _buildRouteOrderTable(
BuildContext context, List<RouteOrderTable>? lstRouteTable) {
return ListView.builder(
itemCount: lstRouteTable == null ? 0 : lstRouteTable.length,
//padding: EdgeInsets.all(8),
itemBuilder: (context, index) {
return Card(
elevation: 4,
child: ListTile(
title: Text(
lstRouteTable == null ? "" : lstRouteTable[index].routeId.toString(),
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text(
lstRouteTable == null ? "" : lstRouteTable[index].processId.toString()),
),
);
},
);
}
You can define the _onReorder function inside the FutureBuilder and then use the snapshot to create a variable of RouteOrderTable.
This will give you access to the removeAt & insert functions.
There are two ways of doing this.
final List<RouteOrderTable>? posts = snapshot.data;
if (snapshot.hasData) {
void _onReorder(int oldIndex, int newIndex){
//1. Define the function here and then pass it as a parameter.
}
routeOrderListSliver = CustomScrollView(
controller: _scrollController,
slivers: <Widget>[
SliverAppBar(
flexibleSpace: FlexibleSpaceBar(
title: Text('ROUTE NO'),
),
),
ReorderableSliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(
title: Text(posts![index].routeId.toString(),
style: TextStyle(fontSize: 20.0),),
),
childCount: posts!.length,
),
onReorder: (int oldIndex, int newIndex){
// OR
// 2. You can directly create the function here.
},
),
],
);
}
Both ways, you get access to the posts variable where you can do your operations.

There should be exactly one item with [DropdownButton]'s value: Instance of 'Partner'

My dropdown working as expected . but when I selected a item my app crashing with error
There should be exactly one item with [DropdownButton]'s value: Instance of 'Partner'.
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
First I declare my variable in class
class _MultipleTestBookingState extends State<MultipleTestBooking> {
Partner? _selectedLab;
Datum? _selectedTest;
....................
declare with Partner?_selectedLab; because my dropdown menu takes in a list of Partners
Then using this variable to show the selected value in my dropdown
Container(
child: FutureBuilder<List<Partner>>(
future: AllPathLab(),
builder:
(BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState !=ConnectionState.done) {
return CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text("Somthing went wrong");
}
if (snapshot.hasData) {
return DropdownButton<Partner>(
value: _selectedLab,
hint: Text("Select Lab"),
items: snapshot.data.map((Partner data) =>
DropdownMenuItem<Partner>(
child: Text("${data.partnerName}"),
value: data,
)
).toList().cast<DropdownMenuItem<Partner>>(),
onChanged: (value){
setState(() {
_selectedLab=value;
encLabId = value!.encPartnerId;
GetTestByLab();
});
}
);
}
return Text("Waiting for Internet Connection");
},
),
),
Full code with my JSON response
So from the data that you provided i have created the code below:
import 'package:date_time_picker/date_time_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/Patner.dart';
import 'package:flutter_app/dataModel.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
const MyApp({Key key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Partner _selectedLab;
Datum _selectedTest;
Future getAllPathLabResults;
Future getTestByLabResult;
String encLabId = '';
void initState() {
super.initState();
getAllPathLabResults = allPathLab();
getTestByLabResult = getTestByLab();
}
String _selectedDate = DateTime.now().toString();
Future<List<Partner>> allPathLab() async {
String jsonData = jsonstring;
final model = modelFromJson(jsonData);
print("This is the list length : ${model.partner.length}");
List<Partner> arrData = model.partner;
// this Future is for sample as you will be fetching the api data remove this one
Future.delayed(Duration(seconds: 3));
return arrData;
}
Future<List<Datum>> getTestByLab() async {
print("This is the Id :$encLabId");
_selectedTest = null;
var response = await http.post(
Uri.parse("http://medbo.digitalicon.in/api/medboapi/GetTestByLab"),
body: ({"EncId": encLabId}));
if (response.statusCode == 200) {
final dataModel = dataModelFromJson(response.body);
print(dataModel.data.length);
for (final item in dataModel.data) {
print("This is hte test name :${item.testName}");
}
List<Datum> arrData = dataModel.data;
return arrData;
}
return [];
}
#override
Widget build(BuildContext context) {
var screenWidth = MediaQuery.of(context).size.width;
var screenHeight = MediaQuery.of(context).size.height;
var blockSizeHorizontal = (screenWidth / 100);
var blockSizeVertical = (screenHeight / 100);
return Scaffold(
body: SafeArea(
child: Container(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: ListTile(
title: Text("Booking Information",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 5,
fontFamily: 'Poppins',
color: Theme.of(context).primaryColor,
)),
subtitle: Text("Preferred Visit Date"),
),
),
Container(
margin: EdgeInsets.only(left: 20),
padding: EdgeInsets.only(left: 0, right: 150),
decoration: BoxDecoration(
color: Colors.lightBlue[50],
borderRadius: BorderRadius.all(Radius.circular(12)),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: DateTimePicker(
initialValue: DateTime.now().toString(),
//initialValue:'', // initialValue or controller.text can be null, empty or a DateTime string otherwise it will throw an error.
type: DateTimePickerType.date,
dateLabelText: 'Select Date',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 3.5,
fontFamily: 'Poppins',
color: Colors.green,
letterSpacing: 2.0,
),
firstDate: DateTime.now(),
lastDate: DateTime.now().add(Duration(days: 30)),
// This will add one year from current date
validator: (value) {
return null;
},
onChanged: (value) {
if (value.isNotEmpty) {
setState(() {
_selectedDate = value;
});
}
},
onSaved: (value) {
if (value.isNotEmpty) {
_selectedDate = value;
}
},
),
),
),
ListTile(
title: Text(
"Select Pathological Lab",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 4.0,
fontFamily: 'Poppins',
color: Theme.of(context).primaryColor,
),
),
),
Container(
child: FutureBuilder<List<Partner>>(
future: getAllPathLabResults,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text("Somthing went wrong");
}
if (snapshot.hasData) {
List<Partner> data =
snapshot.hasData ? snapshot.data : [];
return DropdownButton<Partner>(
value: _selectedLab,
hint: Text("Select Lab"),
//underline: SizedBox(),
//isExpanded: true,
items: data
.map((Partner data) => DropdownMenuItem<Partner>(
child: Text("${data.partnerName}"),
value: data,
))
.toList()
.cast<DropdownMenuItem<Partner>>(),
onChanged: (value) {
setState(() {
_selectedLab = value;
encLabId = value.encPartnerId;
getTestByLabResult = getTestByLab();
});
//GetTestByLab(value!.encPartnerId); // passing encid to my next API function
// GetTestByLab();
},
);
}
return Text("Waiting for Internet Connection");
},
),
),
//=========================================================== Dependent drop down===================================
ListTile(
title: Text(
"Test Name",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 4.0,
fontFamily: 'Poppins',
color: Theme.of(context).primaryColor,
),
),
),
Container(
child: FutureBuilder<List<Datum>>(
future: getTestByLabResult,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text("Select a Lab for your Test");
}
if (snapshot.hasData) {
List<Datum> data = snapshot.hasData ? snapshot.data : [];
return DropdownButton<Datum>(
value: _selectedTest,
hint: Text(""),
//underline: SizedBox(),
//isExpanded: true,
items: data
.map((Datum data) => DropdownMenuItem<Datum>(
child: Text("${data.testName}"),
value: data,
))
.toList()
.cast<DropdownMenuItem<Datum>>(),
onChanged: (value) {
print("This is the value : ${value.testName}");
setState(() {
_selectedTest = value;
});
//GetTestByLab(value!.encPartnerId); // passing encid to my next API function
});
}
return Text("Waiting for Internet Connection");
},
),
),
],
),
),
),
);
}
}
// used this as a sample
String jsonstring = '''{
"Status": "1",
"Message": "",
"Partner": [
{
"EncPartnerId": "IujyQXg8KZg8asLvK/FS7g==",
"PartnerName": "dasfdsf"
},
{
"EncPartnerId": "pEl2B9kuumKRxIxLJO76eQ==",
"PartnerName": "partner172"
},
{
"EncPartnerId": "eYwtNBXR6P/JDtsIwr+Bvw==",
"PartnerName": "nnkb"
},
{
"EncPartnerId": "kFgorcFF0G6RQD4W+LwWnQ==",
"PartnerName": "nnkjj"
},
{
"EncPartnerId": "U4exk+vfMGrn7cjNUa/PBw==",
"PartnerName": "mahadev"
},
{
"EncPartnerId": "tqkaSjTFgDf0612mp9mbsQ==",
"PartnerName": null
},
{
"EncPartnerId": "0aruO0FbYOu5IerRBxdT8w==",
"PartnerName": "Suraksha Diagnostics"
},
{
"EncPartnerId": "65gtodyhbtdInTsJWr1ZkA==",
"PartnerName": "Rasomoy pvt. Hospital"
},
{
"EncPartnerId": "LEuT1eIlpLEMAAkZme3wpQ==",
"PartnerName": "Tangra medical House"
},
{
"EncPartnerId": "q8O8YMzYKXSB4RtkX4k7Lw==",
"PartnerName": "Partner new"
}
]
}''';
Models for the apis:
// To parse this JSON data, do
//
// final model = modelFromJson(jsonString);
import 'dart:convert';
Model modelFromJson(String str) => Model.fromJson(json.decode(str));
String modelToJson(Model data) => json.encode(data.toJson());
class Model {
Model({
this.status,
this.message,
this.partner,
});
String status;
String message;
List<Partner> partner;
factory Model.fromJson(Map<String, dynamic> json) => Model(
status: json["Status"],
message: json["Message"],
partner:
List<Partner>.from(json["Partner"].map((x) => Partner.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"Status": status,
"Message": message,
"Partner": List<dynamic>.from(partner.map((x) => x.toJson())),
};
}
class Partner {
Partner({
this.encPartnerId,
this.partnerName,
});
String encPartnerId;
String partnerName;
factory Partner.fromJson(Map<String, dynamic> json) => Partner(
encPartnerId: json["EncPartnerId"],
partnerName: json["PartnerName"] == null ? null : json["PartnerName"],
);
Map<String, dynamic> toJson() => {
"EncPartnerId": encPartnerId,
"PartnerName": partnerName == null ? null : partnerName,
};
}
second api parsing model
// To parse this JSON data, do
//
// final dataModel = dataModelFromJson(jsonString);
import 'dart:convert';
DataModel dataModelFromJson(String str) => DataModel.fromJson(json.decode(str));
String dataModelToJson(DataModel data) => json.encode(data.toJson());
class DataModel {
DataModel({
this.status,
this.message,
this.data,
});
String status;
String message;
List<Datum> data;
factory DataModel.fromJson(Map<String, dynamic> json) => DataModel(
status: json["Status"],
message: json["Message"],
data: json["Data"] == null
? []
: List<Datum>.from(json["Data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"Status": status,
"Message": message,
"Data":
data == null ? [] : List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
this.testId,
this.encTestId,
this.testName,
this.noOfPartner,
this.testFee,
this.discountedFee,
this.bookingFee,
this.reportTime,
this.note,
this.createBy,
this.createDate,
this.modBy,
this.modDate,
this.activeStatus,
this.permission,
});
String testId;
dynamic encTestId;
String testName;
dynamic noOfPartner;
dynamic testFee;
dynamic discountedFee;
dynamic bookingFee;
dynamic reportTime;
dynamic note;
dynamic createBy;
dynamic createDate;
dynamic modBy;
dynamic modDate;
dynamic activeStatus;
dynamic permission;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
testId: json["TestId"],
encTestId: json["EncTestId"],
testName: json["TestName"],
noOfPartner: json["NoOfPartner"],
testFee: json["TestFee"],
discountedFee: json["DiscountedFee"],
bookingFee: json["BookingFee"],
reportTime: json["ReportTime"],
note: json["Note"],
createBy: json["CreateBy"],
createDate: json["CreateDate"],
modBy: json["ModBy"],
modDate: json["ModDate"],
activeStatus: json["ActiveStatus"],
permission: json["Permission"],
);
Map<String, dynamic> toJson() => {
"TestId": testId,
"EncTestId": encTestId,
"TestName": testName,
"NoOfPartner": noOfPartner,
"TestFee": testFee,
"DiscountedFee": discountedFee,
"BookingFee": bookingFee,
"ReportTime": reportTime,
"Note": note,
"CreateBy": createBy,
"CreateDate": createDate,
"ModBy": modBy,
"ModDate": modDate,
"ActiveStatus": activeStatus,
"Permission": permission,
};
}
So when you initially fetch the data based on the id and select the second dropdown. now when you change the lab you have the make the selected text to null.
and you are are also using the futurebuilder method in wrong manner as there is setstate getting called it is creating multiple rebuids and giving error.
please run the code and check if its working.

Listview with images list not populating Flutter

I want to show images from Json into list. I do not know why it is not parsing images correctly. I am trying to get image from nested list but always it shows error of type list is not type of list.
https://imgur.com/AVGNSdl
My Json is like this
[
{
"PhoneNo": "030780229",
"VehicleNo": "1838",
"Features": "1111",
"Category": "Sedan",
"carsalingImage": [
{
"PhoneNo": "030780229",
"VehicleNo": "1838",
"ImageURL": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/4QBsRXhpZgAASUkqAAgAAAADADEBAgAHAAAA",
"Id": 0
},
{
"PhoneNo": "030780229",
"VehicleNo": "1838",
"ImageURL": "data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/4QBsRXhpZgAASUkqAAgAAAADADEBAgAHAAAA",
"Id": 0
}
]
My build function is
Uint8List _bytesImage;
List<CarSaleImage> userList;
Widget build(BuildContext context) {
return FutureBuilder<List<CarModel>>(
future: _fetchNewVehicles(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<CarModel> data = snapshot.data;
return _showlistView(data);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
);
}
Future<List<CarModel>> _fetchNewVehicles() async {
final response = await http.get(uri);
print(uri);
if (response.statusCode == 200) {
// setState(() {
List jsonResponse = json.decode(response.body);
//
userList = (jsonResponse[0]['carsalingImage'])
.map((itemWord) => CarSaleImage.fromJson(itemWord))
.toList();
print(userList.length);
//
return jsonResponse.map((c) => new CarModel.fromJson(c)).toList();
// });
} else {
throw Exception('Failed to load data from API');
}
}
ListView _showlistView(data) {
return ListView.builder(
itemCount: data == null ? 0 : data.length,
itemBuilder: (context, index) {
return _itemBuilder(
context,
index,
data[index].manufacturerName ??
'' + "Model: " + data[index].model ??
'' + "year: " + data[index].year + '');
});
}
Widget _itemBuilder(BuildContext context, int index, String texts) {
return InkWell(
child: Card(
child: Column(children: <Widget>[
SizedBox(
height: 200.0,
child: ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: userList.length,
itemBuilder: (BuildContext context, int index) => Card(
child: Container(
width: MediaQuery.of(context).size.width - 40,
child: Center(
child: Image(
image:
returnImg(userList[index].imageUrl.toString())
.image))),
),
),
),
Text(
'Demo Headline 2',
),
Container(
height: 50,
child: Text(
"${texts}",
style: TextStyle(
fontWeight: FontWeight.w500,
color: Colors.orange,
),
),
),
])),
onTap: () {
print(texts);
});
}
Image returnImg(String bytesData) {
_bytesImage = base64.decode(bytesData.split(',').last);
return Image.memory(_bytesImage);
}
My Model classes are
CarModel carVecFromJson(String str) => CarModel.fromJson(json.decode(str));
String carVecToJson(CarModel data) => json.encode(data.toJson());
class CarModel {
CarModel({
this.phoneNo,
this.vehicleNo,
this.features,
this.category,
this.carsalingImage,
});
String phoneNo;
String vehicleNo;
String features;
String category;
List<CarSaleImage> carsalingImage;
factory CarModel.fromJson(Map<String, dynamic> json) => CarModel(
phoneNo: json["PhoneNo"],
vehicleNo: json["VehicleNo"],
features: json["Features"],
category: json["Category"],
carsalingImage: List<CarSaleImage>.from(
json["carsalingImage"].map((x) => CarSaleImage.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"PhoneNo": phoneNo,
"VehicleNo": vehicleNo,
"Features": features,
"Category": category,
"carsalingImage":
List<dynamic>.from(carsalingImage.map((x) => x.toJson())),
};
}
class CarSaleImage {
CarSaleImage({
this.phoneNo,
this.vehicleNo,
this.imageUrl,
this.id,
});
String phoneNo;
String vehicleNo;
String imageUrl;
int id;
factory CarSaleImage.fromJson(Map<String, dynamic> json) => CarSaleImage(
phoneNo: json["PhoneNo"],
vehicleNo: json["VehicleNo"],
imageUrl: json["ImageURL"],
id: json["Id"],
);
Map<String, dynamic> toJson() => {
"PhoneNo": phoneNo,
"VehicleNo": vehicleNo,
"ImageURL": imageUrl,
"Id": id,
};
}
How to resolve this issue. Any help ?
Please update CarModel and try again.
factory CarModel.fromJson(Map<String, dynamic> json) => CarModel(
phoneNo: json["PhoneNo"],
vehicleNo: json["VehicleNo"],
features: json["Features"],
category: json["Category"],
carsalingImage:
json["carsalingImage"].map((x) => CarSaleImage.fromJson(x)).toList(),
);
Map<String, dynamic> toJson() => {
"PhoneNo": phoneNo,
"VehicleNo": vehicleNo,
"Features": features,
"Category": category,
"carsalingImage": carsalingImage.map((x) => x.toJson()).toList(),
};

How do I search through data in flutter app

I am new to flutter and I was following a tutorial that shows how to search through data. I cannot recreate that using my own example. I would like to know how to search through data in a ListView from this json data.
{
"success": "true",
"data": [
{
"id": 1,
"name": "football"
},
{
"id": 2,
"name": "rugby"
},
{
"id": 3,
"name": "basketball"
},
{
"id": 4,
"name": "hockey"
},
{
"id": 5,
"name": "tennis"
},
{
"id": 6,
"name": "golf"
}
]
}
Displayed using this code
if (snapshot.hasData) {
return ListView.builder(
itemCount: sports.games.length,
itemBuilder: (context, index) {
if (sports.games.length > 0) {
final x = sports.games[index];
final y = sports.games[index].id.toString();
return ListTile(
title: Text(y),
subtitle: Text(x.name),
);
}
},
);
}
},
First your JSON file will return as a Map, according to this answer at
Unhandled Exception: InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>
for your problem, here is the solution. First you need create a model like this, can be place at separate file or can be place at same file too
class Sports {
int id;
String name;
Sports({
this.id,
this.name,
});
factory Sports.fromJson(Map<String, dynamic> json) {
return Sports(id: json['id'], name: json['name']);
}
}
than here it's the main.dart
import 'package:aberdeen/model.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyApp> {
TextEditingController controller = new TextEditingController();
List<Sports> array = [];
List<Sports> _filtered = [];
List<Sports> _null_filtered = [];
String jsonTest =
'{"success": "true","data": [{"id": 1,"name": "football"},{"id": 2,"name": "rugby"},{"id": 3,"name": "basketball"},{"id": 4,"name": "hockey"},{"id": 5,"name": "tennis"},{"id": 6,"name": "golf"}]}';
void initState() {
super.initState();
test();
}
void _alterfilter(String query) {
List<Sports> dummySearchList = [];
dummySearchList.addAll(_filtered);
if (query.isNotEmpty) {
List<Sports> dummyListData = [];
dummySearchList.forEach((item) {
if (item.name.contains(query)) { //if you want to search it order by id you can change item.name.contains to item.id.contains
dummyListData.add(item);
}
});
setState(() {
_filtered.clear();
_filtered.addAll(dummyListData); //dummyListData will place all the data that match at your search bar
});
return;
} else {
setState(() {
_filtered.clear();
_filtered.addAll(_null_filtered); //_null_filtered will place all the data if search bar was empty after enter a words
});
}
}
Future<Sports> test() async {
Map<String, dynamic> tagObjsJson = json.decode(jsonTest);
List<dynamic> data = tagObjsJson["data"];
setState(() {
for (Map Data in data) {
array.add(Sports.fromJson(Data));
}
_filtered.addAll(array);
_null_filtered.addAll(array);
for (int a = 0; a < _filtered.length; a++) {
print(_filtered[a].name);
}
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
alignment: Alignment.center,
child: Container(
margin: const EdgeInsets.only(top: 50),
width: 300,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
border: Border.all(
width: 1,
color: Color.fromRGBO(11, 189, 180, 1),
style: BorderStyle.solid)),
child: TextField(
decoration: InputDecoration(
hintText: 'Search your data',
contentPadding: EdgeInsets.all(15),
border: InputBorder.none),
controller: controller,
onChanged: (value) {
_alterfilter(value);
},
),
),
),
],
),
Expanded(
child: Container(
margin: const EdgeInsets.all(20),
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _filtered.length,
itemBuilder: (context, index) {
if (array.length > 0) {
final x = _filtered[index];
final y = _filtered[index].id.toString();
return ListTile(
title: Text(y),
subtitle: Text(x.name),
);
}
},
),
))
],
),
),
));
}
}
Sorry mate if my english was very bad but tell me if you got confused