ReorderableSliverList with Futurebuilder - json

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.

Related

How to display JSON data?

How to display DietName which is under Data? I can display the item which is under PartnerData[] But what is the syntax just to display DietName?
{
"Status": "1",
"Message": "",
"Data": {
"EncDietId": "pEl2B9kuumKRxIxLJO76eQ==",
"DietName": "dietcian2",
"Email": null,
"Phone": null,
"AlternatePhone": null,
"Image": "http://mjjjjctor/65AUEYMCUE8RTD2UKBRV.jpg",
"Description": null,
"Fee": null,
"DiscountedFee": null,
"BookingFee": null,
"VisitDay": null,
"TimeFrom": null,
"TimeTo": null
},
"PartnerData": [
{
"PartnerId": "13",
"EncPartnerId": "65gtodyhbtdInTsJWr1ZkA==",
"PartnerName": "Rasomoy pvt. Hospital",
"PartnerAddress": "Kol,Kol,Kol,Wb",
"Fee": "1200",
"DiscountedFee": "900",
"BookingFee": "500",
"DayList": [
{
"DayName": "Wednesday",
"TimeFrom": "10:00",
"TimeTo": "16:00"
},
{
"DayName": "Friday",
"TimeFrom": "10:00",
"TimeTo": "16:00"
},
{
"DayName": "Saturday",
"TimeFrom": "10:00",
"TimeTo": "16:00"
}
]
}
]
}
Model class:
DietDetailsModel dietDetailsModelFromJson(String str) => DietDetailsModel.fromJson(json.decode(str));
String dietDetailsModelToJson(DietDetailsModel data) => json.encode(data.toJson());
class DietDetailsModel {
DietDetailsModel({
required this.status,
required this.message,
required this.data,
required this.partnerData,
});
String status;
String message;
Data data;
List<PartnerDatum> partnerData;
factory DietDetailsModel.fromJson(Map<String, dynamic> json) => DietDetailsModel(
status: json["Status"],
message: json["Message"],
data: Data.fromJson(json["Data"]),
partnerData: List<PartnerDatum>.from(json["PartnerData"].map((x) => PartnerDatum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"Status": status,
"Message": message,
"Data": data.toJson(),
"PartnerData": List<dynamic>.from(partnerData.map((x) => x.toJson())),
};
}
class Data {
Data({
required this.encDietId,
required this.dietName,
required this.email,
required this.phone,
required this.alternatePhone,
required this.image,
required this.description,
required this.fee,
required this.discountedFee,
required this.bookingFee,
required this.visitDay,
required this.timeFrom,
required this.timeTo,
});
String encDietId;
String dietName;
dynamic email;
dynamic phone;
dynamic alternatePhone;
String image;
dynamic description;
dynamic fee;
dynamic discountedFee;
dynamic bookingFee;
dynamic visitDay;
dynamic timeFrom;
dynamic timeTo;
factory Data.fromJson(Map<String, dynamic> json) => Data(
encDietId: json["EncDietId"],
dietName: json["DietName"],
email: json["Email"],
phone: json["Phone"],
alternatePhone: json["AlternatePhone"],
image: json["Image"],
description: json["Description"],
fee: json["Fee"],
discountedFee: json["DiscountedFee"],
bookingFee: json["BookingFee"],
visitDay: json["VisitDay"],
timeFrom: json["TimeFrom"],
timeTo: json["TimeTo"],
);
Map<String, dynamic> toJson() => {
"EncDietId": encDietId,
"DietName": dietName,
"Email": email,
"Phone": phone,
"AlternatePhone": alternatePhone,
"Image": image,
"Description": description,
"Fee": fee,
"DiscountedFee": discountedFee,
"BookingFee": bookingFee,
"VisitDay": visitDay,
"TimeFrom": timeFrom,
"TimeTo": timeTo,
};
}
My API
Future<List<PartnerDatum>> dietcianDetailsApi() async {
var jsonResponse;
var response = await http.post(
Uri.parse("http://mjjjjapi/DietDetails"),
body: ({
'EncId': encDietcianIdRef,
}));
if (response.statusCode == 200) {
print("Correct");
print(response.body);
jsonResponse = json.decode(response.body.toString());
print(jsonResponse);
//Navigator.push(context, MaterialPageRoute(builder: (context)=>AfterSearchPage(rresponse: SearchApiResponse.fromJson(jsonResponse))));
DietDetailsModel dataModel = dietDetailsModelFromJson(response.body);
print(dataModel.partnerData.length);
for (final item in dataModel.partnerData)
print(item.partnerName);
List<PartnerDatum> arrData =dataModel.partnerData;
// print(arrData[1].partnerName);
return arrData;
} else {
print("Wrong Url");
print(response.body);
throw Exception("Faild to fetch");
}
//return AllDietician();
}
Printing My PartnerData items . But How to display DietName which is inside Data?
class DietcianDetailsPage extends StatefulWidget {
var encDietcianId;
DietcianDetailsPage(this.encDietcianId);
#override
_DietcianDetailsPageState createState() => _DietcianDetailsPageState(this.encDietcianId);
}
class _DietcianDetailsPageState extends State<DietcianDetailsPage> {
var encDietcianIdRef;// Need to pass is encId as a parameter in dietcianDetails Api
_DietcianDetailsPageState(this.encDietcianIdRef);
#override
void initState() {
dietcianDetailsApi();
super.initState();
}
#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(
appBar: AppBar(
elevation: 0.0,
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.topRight,
colors: [
Theme.of(context).primaryColor,
Theme.of(context).accentColor
],
),
),
),
title: Center(
child: Image.asset(
"assets/images/medbo.png",
fit: BoxFit.contain,
height: 52,),
),
//toolbarHeight: 88,
actions: [
IconButton(onPressed: () => {}, icon: Icon(Icons.more_vert,size: 0.1,),),
],
),
body: Container(
child: Column(
children: [
Text(
""
),
//========================================================================
Container(
height: blockSizeVertical*30,//38
//color: Colors.blueAccent,
child: FutureBuilder(
future: dietcianDetailsApi(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
// if (snapshot.connectionState !=ConnectionState.done) {
// return CircularProgressIndicator();
// }
if (snapshot.hasError) {
return Text("Somthing went wrong");
}
if (snapshot.hasData) {
return ListView.builder(
scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(),
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) =>
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
width: blockSizeHorizontal*80,
margin: EdgeInsets.all(10),
child: Stack(children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(//====================images
padding: const EdgeInsets.all(5.0),
),
SizedBox(height: blockSizeVertical*0.5),
Text(
'PartnerName : ${snapshot.data[index].partnerName}',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal*3.5,
fontFamily: 'Poppins',
color: Theme.of(context).primaryColor,
),
textAlign: TextAlign.center,
),
The problem is dietcianDetailsApi because you return a List< PartnerDatum> and this model doesn't contains a DietName.
First solution is modify your function (dietcianDetailsApi), needs modify the data type that this function return, because the DietDetailsModel model contains both variables that you need.
Example:
Inside of dietcianDetailsApi you can assign the value, like this:
Future<DietDetailsModel> dietcianDetailsApi() async {
var jsonResponse;
var response = await http.post(
Uri.parse("http://medbo.digitalicon.in/api/medboapi/DietDetails"),
body: ({
'EncId': encDietcianIdRef,
}));
if (response.statusCode == 200) {
jsonResponse = json.decode(response.body.toString());
DietDetailsModel dataModel = dietDetailsModelFromJson(response.body);
return dataModel
} else {
print("Wrong Url");
print(response.body);
throw Exception("Faild to fetch");
}
Finally, you can replace your FutureBuilder for this:
FutureBuilder(
future: dietcianDetailsApi(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasError) {
return Text("Somthing went wrong");
}
if (snapshot.hasData) {
var dietDetails = snapshot.data;
print('PartnerData: ${dietDetails.partnerData}');
print('DietName: ${dietDetails.data.dietName}');
// ADD YOUR CODE
}
}
),
Your Future is returning only the partnerData while it could as well return the whole DietDetailsModel in one object.
If you return the DietDetailsModel dataModel you could then consume the response in DietcianDetailsPage. Your ListView would use dataModel.data.partnerData but you could also access dataModel.data.data.
I hope I did not mix up the fields in your code.

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

Prevent null values from showing up in ListView from JSON response Flutter

I have a listView of contacts from API response, I want to leave out all the contacts whose firstname and lastname is NULL because I'm getting the NoSuchMethodError.
I tried using return contact.fields.all.firstname == null ? Container() : InkWell(child: Container(...)) condition and returning an empty container but that just leaves an empty space in the UI, so i was hoping to filter out all the null contacts before rendering it in the UI itself, so for that I used snapshot.data.contacts.removeWhere((key, value) => contact.fields.all.firstname == null && contact.fields.all.lastname == null); but it still did not work.
Are there any other ways to filter it out or return any empty widget in the condition which doesn't affect the UI much?
My JSON sample code:
{
"total": "187144",
"contacts": {
"897": {
"isPublished": true,
"id": 897,
"fields": {
"core": {
"points": {
"id": "47",
"label": "Points"
},
"firstname": {
"id": "2",
"label": "First Name",
"value": "Jason"
},
"lastname": {
"id": "3",
"label": "Last Name",
"value": "Lamuda"
},
"...": {
"..." : "..."
}
},
"ipAddresses": [
{
"ip": "70.127.91.131",
"ipDetails": {
"city": "Bradenton",
"region": "Florida",
"timezone": "America/New_York",
}
},
"...": {
"..." : "..."
}
API_Manager class:
Future<ContactsModel> getContacts() async {
var client = http.Client();
var contactsModel;
String getContactUrl =
'https://example.com/ma/api/contacts';
String basicAuth = 'Basic exampleauthkey';
try {
var response = await client.get(getContactUrl, headers: <String, String>{
'content-type': 'application/json',
"Accept": "application/json",
'authorization': basicAuth,
});
print(response.statusCode);
developer.log(response.body);
if (response.statusCode == 200) {
var jsonString = response.body;
var jsonMap = json.decode(jsonString);
contactsModel = ContactsModel.fromJson(jsonMap);
}
} catch (Exception) {
return contactsModel;
}
return contactsModel;
}
UI Code:
child: FutureBuilder<ContactsModel>(
future: _contactsModel,
builder: (BuildContext context,
AsyncSnapshot<ContactsModel> snapshot) {
if (snapshot.hasData) {
return ListView.separated(
shrinkWrap: true,
padding: const EdgeInsets.all(8),
itemCount: snapshot.data.contacts.length,
itemBuilder: (BuildContext context, int index) {
List keys = snapshot.data.contacts.keys.toList();
List values =
snapshot.data.contacts.values.toList();
var contact = values[index]; //Single contact object here
final contactID = contact.id.toString();
return InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ViewContact(
contact, contactID)));
},
child: Container(
height: 50,
color: Colors.white,
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Text(
contact.fields.all.firstname +
" " +
contact.fields.all.lastname,
style: TextStyle(fontSize: 16),
),
],
),
),
);
},
separatorBuilder:
(BuildContext context, int index) {
return SizedBox(
height: 5,
);
},
);
} else
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.blueGrey[700],
valueColor: AlwaysStoppedAnimation<Color>(
Colors.cyan)));
}),
snapshot.data.contacts.removeWhere(
(key, value) => (
(contact.fields.all.firstname == null || contact.fields.all.firstname == '') &&
(contact.fields.all.lastname == null || contact.fields.all.lastname == '')
)
);

How to get value from Instance of JSON in Flutter?

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,
),
),