Related
So basically it is a comment box that comes with or without an image. So the img url is nullable. I am trying to deserialize it.
Here is the Comment Model.
// To parse this JSON data, do
//
// final productComment = productCommentFromJson(jsonString);
import 'package:meta/meta.dart';
import 'dart:convert';
ProductComment productCommentFromJson(String str) =>
ProductComment.fromJson(json.decode(str));
String productCommentToJson(ProductComment data) => json.encode(data.toJson());
class ProductComment {
const ProductComment({
this.id,
this.comment,
this.owner,
this.productId,
this.imgsUrl,
this.imgsName,
this.createdAt,
});
final int? id;
final String? comment;
final String? owner;
final int? productId;
final List<String>? imgsUrl;
final List<String>? imgsName;
final DateTime? createdAt;
factory ProductComment.fromJson(Map<String, dynamic> json) => ProductComment(
id: json["id"],
comment: json["comment"],
owner: json["owner"],
productId: json["product_id"],
// imgsUrl: List<String>.from(json["imgs_url"].map((x) => x)),
imgsUrl: json["imgs_url"] == null
? null
: List<String>.from(json["imgs_url"].map((x) => x)),
imgsName: List<String>.from(json["imgs_name"].map((x) => x)),
createdAt: DateTime.parse(json["created_at"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"comment": comment,
"owner": owner,
"product_id": productId,
"imgs_name": List<dynamic>.from(imgsName!.map((x) => x)),
// "imgs_url": List<dynamic>.from(imgsUrl!.map((x) => x)),
"imgs_url":
imgsUrl == null ? null : List<dynamic>.from(imgsUrl!.map((x) => x)),
"created_at": createdAt!.toIso8601String(),
};
}
I am trying to decode the imgs_url wether it has an image or not.
Wrap(
children: <Widget>[
Card(
margin: const EdgeInsets.all(8),
child: Container(
decoration: const BoxDecoration(
color: Color.fromARGB(255, 221, 217, 217),
borderRadius: BorderRadius.all(Radius.circular(10))),
padding:
const EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
child: Column(
children: <Widget>[
Container(
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: Isize().borderRadius),
child: Text(
widget.comment,
overflow: flag ? TextOverflow.ellipsis : null,
style: const TextStyle(
fontSize: 15,
),
),
),
InkWell(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(
flag ? "show more" : "show less",
style: const TextStyle(
color: lilac, fontFamily: 'FiraCode'),
),
],
),
onTap: () {
setState(() {
flag = !flag;
});
},
),
Builder(builder: (context) {
if (widget.image!.isNotEmpty) {
return Container();
}
return SizedBox(
height: 100,
child: GridView.count(
mainAxisSpacing: 1,
crossAxisSpacing: 1,
crossAxisCount: 6,
children:
List.generate(widget.image!.length, (index) {
return Center(
child: CachedNetworkImage(
memCacheHeight: 20,
memCacheWidth: 20,
imageUrl: widget.image![index]!,
imageBuilder: (context, imageProvider) =>
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
borderRadius: Isize().borderRadius,
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
colorFilter: const ColorFilter.mode(
Colors.black45,
BlendMode.darken,
),
),
),
),
placeholder: (context, url) => Center(
child: Image.asset(IhIcon().ihemyilogo),
),
errorWidget: (context, url, error) =>
const Icon(
Icons.error,
color: Colors.deepOrangeAccent,
),
),
);
}),
));
})
],
)),
),
],
);
For the repository which also has a map:
Future<List<ProductComment>> productCommentsByID(int productID) async {
final uri = Uri.parse('${ep.mainUrl}/api/v1/products/comments/$productID');
debugPrint('Comments by Product ID = $uri');
final response = await http.get(uri);
if (response.statusCode == 200) {
if (response.body.isNotEmpty) {
final comments = List<ProductComment>.from(
json.decode(response.body).map(
(data) => ProductComment.fromJson(data),
),
);
debugPrint('Fucker says hello ${comments.toString()}');
return comments;
} else {
throw ErrorEmptyResponse();
}
} else {
throw ErrorGettingGames(
'Error getting Comments With Product ID $productID');
}
}
Please i need help.I cant understand which of the maps that has the issue. I just get this error:
I/flutter ( 3603): Transition { currentState: CommentState([], Instance of 'ProductComment', 0, CommentStatus.error), event: CommentsByProductID(1), nextState: CommentError(NoSuchMethodError: The method 'map' was called on null.
I/flutter ( 3603): Receiver: null
I think your imgsName may be null too, try change this:
imgsName: List<String>.from(json["imgs_name"].map((x) => x)),
to this:
imgsName: json["imgs_name"] == null? null: List<String>.from(json["imgs_name"].map((x) => x)),
I wanted to take inspiration from this code below with a mysql database, but I don't get the same result
Here is the code I want to inspire
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:flutter_sorting_location/Destination.dart';
import 'package:flutter_sorting_location/Utils.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
Position? _currentPosition;
List<Destination> destinationlist = [];
#override
void initState() {
_getCurrentLocation();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Location sorting from current location"),
),
body: Container(
child: destinationlist.length > 0
? ListView.builder(
itemCount: destinationlist.length,
itemBuilder: (context, index) {
return Card(
margin: EdgeInsets.all(5),
elevation: 5,
child: Padding(
padding: EdgeInsets.all(5),
child: Container(
height: 40,
color: Colors.white,
child: Column(
children: [
Text("${destinationlist[index].name}"),
Text(
"${destinationlist[index].distance!.toStringAsFixed(2)} km"),
],
),
),
),
);
})
: Center(
child: CircularProgressIndicator(),
)));
}
// get Current Location
_getCurrentLocation() {
Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best,
forceAndroidLocationManager: true)
.then((Position position) {
distanceCalculation(position);
setState(() {
_currentPosition = position;
});
}).catchError((e) {
print(e);
});
}
distanceCalculation(Position position) {
for (var d in destinations) {
var km = getDistanceFromLatLonInKm(
position.latitude, position.longitude, d.lat, d.lng);
// var m = Geolocator.distanceBetween(position.latitude,position.longitude, d.lat,d.lng);
// d.distance = m/1000;
d.distance = km;
destinationlist.add(d);
// print(getDistanceFromLatLonInKm(position.latitude,position.longitude, d.lat,d.lng));
}
setState(() {
destinationlist.sort((a, b) {
// print("a : ${a.distance} b : ${b.distance}");
return a.distance!.compareTo(b.distance!);
});
});
}
}
with
print("a : ${a.distance} b : ${b.distance}");
we get fine distance like
I/flutter (11628): a : 0.013746775325924289 b : 1.6212196943125314
I/flutter (11628): a : 1.6212196943125314 b : 2.298635770797528
I/flutter (11628): a : 2.298635770797528 b : 54.66693675805389
I/flutter (11628): a : 54.66693675805389 b : 42.21435296268619
I/flutter (11628): a : 2.298635770797528 b : 42.21435296268619
I/flutter (11628): a : 54.66693675805389 b : 5.6902906741853565
I/flutter (11628): a : 42.21435296268619 b : 5.6902906741853565
I/flutter (11628): a : 2.298635770797528 b : 5.6902906741853565
I/flutter (11628): a : 54.66693675805389 b : 11.105760783520099
I/flutter (11628): a : 42.21435296268619 b : 11.105760783520099
I/flutter (11628): a : 5.6902906741853565 b : 11.105760783520099
and this again
Text(
"${destinationlist[index].distance!.toStringAsFixed(2)} km"),
but with my code i don't have that.
with
print("a : $a.distance B : $b.distance");
i have
I/flutter (11761): a : {nom: CLINIQUE CENTRE, latitude: 37.7586968, longitude: -122.3053474, distance: 42.21435296268619}.distance B : {nom: CLINIQUE CHATEAU, latitude: 37.8711583, longitude: -122.336457, distance: 54.66693675805389}.distance
I/flutter (11761): a : {nom: CLINIQUE CHATEAU, latitude: 37.8711583, longitude: -122.336457, distance: 54.66693675805389}.distance B : {nom: CLINIQUE ARAFAT, latitude: 37.5206515, longitude: -122.064364, distance: 11.105760783520099}.distance
I/flutter (11761): a : {nom: CLINIQUE CENTRE, latitude: 37.7586968, longitude: -122.3053474, distance: 42.21435296268619}.distance B : {nom: CLINIQUE ARAFAT, latitude: 37.5206515, longitude: -122.064364, distance: 11.105760783520099}.distance
here is what i tried
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:flutter_sorting_location/Utils.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:flutter_sorting_location/Destination.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
double? distance;
List destinations = [];
Position? _currentPosition;
List<Destination> destinationlist = [];
Future<List> getData() async {
var url = 'http://aidemens.global-aeit.com/flutter/getlocation.php';
print(url);
final response = await http.get(Uri.parse(url));
// print(json.decode(response.body));
destinations = json.decode(response.body);
return json.decode(response.body);
}
#override
void initState() {
_getCurrentLocation();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Location sorting from current location"),
),
body: FutureBuilder<List>(
future: getData(),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
// print(snapshot.data!);
return Card(
margin: EdgeInsets.all(5),
elevation: 5,
child: Padding(
padding: EdgeInsets.all(5),
child: Container(
height: 40,
color: Colors.white,
child: Column(
children: [
Text("${snapshot.data![index]['nom']}"),
Text(
"${double.parse(snapshot.data![index]['distance']!).toStringAsFixed(2)} km"),
],
),
),
),
);
})
: const Center(
child: Text(
"Aucun encaissement ce jour",
style: TextStyle(color: Colors.red),
),
);
}));
}
// get Current Location
_getCurrentLocation() {
Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best,
forceAndroidLocationManager: true)
.then((Position position) {
distanceCalculation(position);
setState(() {
_currentPosition = position;
});
}).catchError((e) {
print(e);
});
}
List tmp = [];
distanceCalculation(Position position) {
tmp.clear();
for (var i = 0; i < destinations.length; i++) {
// print("latitude : " + destinations[i]['latitude']);
var km = getDistanceFromLatLonInKm(
position.latitude,
position.longitude,
double.parse(destinations[i]['latitude']),
double.parse(destinations[i]['longitude']));
// print("distance : ${km} ");
destinations[i]['distance'] = km;
// print(destinations[i]['distance']);
destinations[i]['distance'] = destinations[i]['distance'];
print(destinations);
// destinations.add(destinations[i]['distance']);
//print(d.distance);
//destinationlist.add(d);
}
setState(() {
destinations.sort((a, b) {
print("a : $a.distance B : $b.distance");
return double.parse(a['distance'].toString())
.compareTo(double.parse(b['distance'].toString()));
});
});
}
}
I am trying to retrieve the data and displaying in a list view but it is showing an error.
The following NoSuchMethodError was thrown building expanse(dirty, dependencies: [MediaQuery], state: _expanseState#6acc3):
The getter 'data' was called on null.
Receiver: null
Tried calling: data
The relevant error-causing widget was:
expanse file:///C:/Users/sindh/AndroidStudioProjects/final_project/lib/Dashboard.dart:261:91
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 _expanseState.build (package:hrms_project/Expenses/expencedashboard.dart:258:39)
#2 StatefulElement.build (package:flutter/src/widgets/framework.dart:4612:27)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4495:15)
#4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4667:11)
I/flutter (16460): 200
E/flutter (16460): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: NoSuchMethodError: The getter 'histories' was called on null.
E/flutter (16460): Receiver: null
E/flutter (16460): Tried calling: histories
E/flutter (16460): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
E/flutter (16460): #1 _expanseState.initState.<anonymous closure> (package:hrms_project/Expenses/expencedashboard.dart:24:27)
E/flutter (16460): #2 _rootRunUnary (dart:async/zone.dart:1362:47)
E/flutter (16460): #3 _CustomZone.runUnary (dart:async/zone.dart:1265:19)
E/flutter (16460): #4 _FutureListener.handleValue (dart:async/future_impl.dart:152:18)
E/flutter (16460): #5 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:704:45)
E/flutter (16460): #6 Future._propagateToListeners (dart:async/future_impl.dart:733:32)
E/flutter (16460): #7 Future._completeWithValue (dart:async/future_impl.dart:539:5)
E/flutter (16460): #8 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:254:13)
E/flutter (16460): #9 Services.getExpense (package:hrms_project/Api.dart)
E/flutter (16460): <asynchronous suspension>
This is json decode code
import 'dart:convert';
Expense expenseFromJson(String str) => Expense.fromJson(json.decode(str));
String expenseToJson(Expense data) => json.encode(data.toJson());
class Expense {
Expense({
this.success,
this.statusCode,
this.data,
this.message,
});
bool success;
int statusCode;
Data data;
String message;
factory Expense.fromJson(Map<String, dynamic> json) => Expense(
success: json["success"],
statusCode: json["statusCode"],
data: Data.fromJson(json["data"]),
message: json["message"],
);
Map<String, dynamic> toJson() => {
"success": success,
"statusCode": statusCode,
"data": data.toJson(),
"message": message,
};
}
class Data {
Data({
this.histories,
});
List<History> histories;
factory Data.fromJson(Map<String, dynamic> json) => Data(
histories: List<History>.from(json["histories"].map((x) => History.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"histories": List<dynamic>.from(histories.map((x) => x.toJson())),
};
}
class History {
History({
this.id,
this.employeeId,
this.reference,
this.categoryId,
this.currencyId,
this.amount,
this.date,
this.merchant,
this.description,
this.attachments,
this.companyId,
this.status,
});
int id;
EmployeeId employeeId;
Reference reference;
String categoryId;
String currencyId;
String amount;
Date date;
String merchant;
String description;
String attachments;
CompanyId companyId;
String status;
factory History.fromJson(Map<String, dynamic> json) => History(
id: json["id"],
employeeId: employeeIdValues.map[json["employee_id"]],
reference: referenceValues.map[json["reference"]],
categoryId: json["category_id"],
currencyId: json["currency_id"],
amount: json["amount"],
date: dateValues.map[json["date"]],
merchant: json["merchant"],
description: json["description"],
attachments: json["attachments"],
companyId: companyIdValues.map[json["company_id"]],
status: json["status"],
);
Map<String, dynamic> toJson() => {
"id": id,
"employee_id": employeeIdValues.reverse[employeeId],
"reference": referenceValues.reverse[reference],
"category_id": categoryId,
"currency_id": currencyId,
"amount": amount,
"date": dateValues.reverse[date],
"merchant": merchant,
"description": description,
"attachments": attachments,
"company_id": companyIdValues.reverse[companyId],
"status": status,
};
}
enum CompanyId { ECS_934284 }
final companyIdValues = EnumValues({
"ECS-934284": CompanyId.ECS_934284
});
enum Date { THE_00000000 }
final dateValues = EnumValues({
"0000-00-00": Date.THE_00000000
});
enum EmployeeId { EMPMOB_006 }
final employeeIdValues = EnumValues({
"EMPMOB-006": EmployeeId.EMPMOB_006
});
enum Reference { USER }
final referenceValues = EnumValues({
"user": Reference.USER
});
class EnumValues<T> {
Map<String, T> map;
Map<T, String> reverseMap;
EnumValues(this.map);
Map<T, String> get reverse {
if (reverseMap == null) {
reverseMap = map.map((k, v) => new MapEntry(v, k));
}
return reverseMap;
}
}
This is the API code
class Services {
static const String url = 'basic url';
static Future <Expense> getExpense() async {
final response = await http.get(Uri.parse('basic url'));
print(response.statusCode);
if(200 == response.statusCode){
final Expense = expenseFromJson(response.body);
return Expense;
}else{
return Expense();
}
}
}
This is the UI
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_session/flutter_session.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hrms_project/Api.dart';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
class getdata {
String category;
String date;
String merchant;
String reference;
String description;
String currencytype;
String amount;
String tax;
getdata({
#required this.category,
#required this.date,
#required this.merchant,
#required this.reference,
#required this.description,
#required this.currencytype,
#required this.amount,
#required this.tax,
});
}
class editpage extends StatefulWidget {
#override
_editpageState createState() => _editpageState();
}
class _editpageState extends State<editpage> {
String SelectDate="Click and select date";
String ctype = "SGD";
String doller = "1";
String _category;
List Category = [
'Allowance',
'Dental Claim',
'Fuel Expense',
'Home base-Taxi/Car RENTAL',
'Home base -mileage',
'IT and Internet Expense',
'Meals and Entertainment',
'Medical Claim',
'Office Supplies',
'Other Expense',
'Transport Claims',
'Travel-Airline',
'Travel-Overseas Allowance',
'Travel Claim',
];
String currencychoose;
List listcurrency = [
'SGD', 'CNY', 'MYR', 'THB', 'TWD', 'USD', 'VND', 'EUR', 'HKD', 'IDR', 'JPY',
];
String taxchoose;
List listTax = [
'GST 0% (0%)',
'GST 7% (7%)',
'Service Charge 10% (10%) ',
];
String Report;
List report = [
"PO-0049-Dominic's",
"PO-0048-April Japan Trip Project",
"PO-0045-Project A March 2021",
"PO-0044-Local Transport-SG",
"PO-0037-Nov2020 Claims",
];
var claimsController = new TextEditingController();
var currencyController = new TextEditingController();
var taxController = new TextEditingController();
var reporttypeController = new TextEditingController();
var merchantController = new TextEditingController();
var selectdateController = new TextEditingController();
var referenceController = new TextEditingController();
var descriptionController = new TextEditingController();
var amountController = new TextEditingController();
void getItemNavigate(BuildContext context) {
Navigator.pop(context);
print("Merchant Name is : ${merchantController.text}");
print("Select Date : ${selectdateController.text}");
print("Reference Code is : ${referenceController.text}");
print("Description is : ${descriptionController.text}");
print("Claims is: ${claimsController.text}");
print("Select Tax : ${taxController.text}");
print(" Amount : ${currencyController.text} ${amountController.text}");
print("Currency Value: ${currencyController.text}");
print("Report: ${reporttypeController.text}");
}
DateTime date = DateTime.now();
Future DatePicker(BuildContext context) async {
final DateTime picked = await showDatePicker(
context: context,
initialDate: date,
firstDate: new DateTime(DateTime
.now()
.year - 50),
lastDate: new DateTime(DateTime
.now()
.year + 50),
);
if (picked != null && picked != date) {
setState(() {
date = picked;
print(date.toString());
selectdateController.text=DateFormat.yMMMd().format(date).toString();
SelectDate =DateFormat.yMMMd().format(date).toString();
});
}
}
File _pickedImage;
void _pickImageCamera() async{
final picker= await ImagePicker();
final pickedImage= await picker.getImage(source:ImageSource.camera);
final pickedImageFile =File(pickedImage.path);
setState((){
_pickedImage =pickedImageFile;
});
Navigator.pop(context);
}
void _pickImageGallery() async{
final picker= await ImagePicker();
final pickedImage= await picker.getImage(source:ImageSource.gallery);
final pickedImageFile = File(pickedImage.path);
setState((){
_pickedImage =pickedImageFile;
});
Navigator.pop(context);
}
void _Remove(){
setState((){
_pickedImage= null;
});
Navigator.pop(context);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
toolbarHeight: MediaQuery
.of(context)
.size
.height * 0.1,
backgroundColor: Colors.lightBlue[300],
leading: IconButton(icon: Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
Navigator.pop(context);
},
),
centerTitle: true,
title: Text('Edit Expense', style: TextStyle(
fontSize: 20, color: Colors.black, fontWeight: FontWeight.bold),),
),
body: SingleChildScrollView(
child: Container(
color:Colors.grey[200],
child: Container(
width: MediaQuery
.of(context)
.size
.width,
margin: EdgeInsets.only(top:20.0,left: 10,right: 10),
padding: EdgeInsets.all(8.0),
color:Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.only(left: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Category', style: TextStyle(fontSize: 16.0,
fontWeight: FontWeight.w600,
color: Colors.grey[800],)),
SizedBox(height: 8.0),
Container(
margin: EdgeInsets.only(left: 40.0),
child: Padding(
padding: const EdgeInsets.all(1.0),
child: Container(
padding: EdgeInsets.only(left: 16.0, right: 16.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(5.0),
),
child: DropdownButton(
hint: Text('Select Category'),
icon: Icon(
Icons.arrow_drop_down, color: Colors.blue,),
iconSize: 30,
value: _category,
onChanged: (newValue) {
setState(() {
_category = newValue;
claimsController.text=_category;
});
},
items: Category.map((valueItem) {
return DropdownMenuItem(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
),
),
),
),
],
),
),
SizedBox(height: 10),
Radius: BorderRadius.circular(5.0),
),
child: ListTile(
title: Text("${SelectDate}", style: TextStyle(
fontSize: 17, color: Colors.grey[600]),),
trailing: Icon(Icons.arrow_drop_down,color: Colors.blueAccent,size:30),
onTap: () {
DatePicker(context);
},
),
),
),
],
),
),
Container(
width: 180,
height: 50,
child: TextField(
controller: amountController,
textAlign: TextAlign.end,
decoration: InputDecoration(
hintText: "Enter Amount",
border: OutlineInputBorder(
),
),
keyboardType: TextInputType.number,
),
),
],
),
),
],
),
),
child: Row(
children: [
Container(
width: 70,
height: 48,
color: Colors.grey[100],
child: Center(
child: Text('1 ${ctype} =',style:TextStyle(fontSize:16.0,color:Colors.black,)),
),
),
Container(
width: 140,
height: 48,
color: Colors.grey[300],
child: Center(
child: Text('${doller}',style:TextStyle(fontSize:16.0,color:Colors.black,)),
),
),
Container(
width: 47,
height: 48,
color: Colors.grey[100],
child: Center(
child: Text('SGD'),
),
),
],
),
),
],
),
),
SizedBox(height: 10.0),
Container(
margin: EdgeInsets.only(left: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Tax', style: TextStyle(fontSize: 16.0,
fontWeight: FontWeight.w600,
color: Colors.grey[800],)),
SizedBox(height: 6.0),
Container(
margin: EdgeInsets.only(left: 40.0),
child: Padding(
padding: const EdgeInsets.all(1.0),
child: Container(
padding: EdgeInsets.only(left: 16.0, right: 16.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(5.0),
),
child: DropdownButton(
hint: Text('Please select the Tax'),
icon: Icon(
Icons.arrow_drop_down, color: Colors.blue,),
iconSize: 30,
value: taxchoose,
onChanged: (newValue) {
setState(() {
taxchoose = newValue;
taxController.text=taxchoose;
});
},
items: listTax.map((valueItem) {
return DropdownMenuItem(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
),
),
),
),
],
),
)
Container(
margin:EdgeInsets.only(left: 30),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('Click and select files-->',style: TextStyle(fontSize: 16.0,color:Colors.red),),
RawMaterialButton(
elevation: 6.0,
child: Icon(
Icons.add_a_photo, size: 40, color: Colors.blue,),
padding: EdgeInsets.all(8.0),
shape: CircleBorder(),
onPressed: () {
showDialog(context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Choose option', style: TextStyle(
fontWeight: FontWeight.w600,
color: Colors.pinkAccent,),
textAlign: TextAlign.center,
),
content: SingleChildScrollView(
child: ListBody(
children: [
InkWell(
onTap:_pickImageCamera,
splashColor: Colors.purpleAccent,
child: Row(
crossAxisAlignment: CrossAxisAlignment
.center,
),
),
SizedBox(height: 5,),
InkWell(
onTap:_pickImageGallery,
splashColor: Colors.purpleAccent,
child: Row(
crossAxisAlignment: CrossAxisAlignment
.center,
children: [
Padding(
padding: EdgeInsets.all(8.0),
child: Icon(Icons.image,
color: Colors
.purpleAccent,
size: 25)
),
Text('Gallery', style: TextStyle(
fontSize: 18,
color: Colors.black,)),
],
),
),
SizedBox(
height: 5
),
InkWell(
onTap:_Remove,
splashColor: Colors.purpleAccent,
child: Row(
crossAxisAlignment: CrossAxisAlignment
.center,
children: [
Padding(
padding: EdgeInsets.all(8.0),
child: Icon(Icons.remove_circle,
color: Colors.purpleAccent,
size: 25),
),
],
),
)
],
),
),
);
});
},
),
],
),
),
SizedBox(height:10.0),
Divider(height: 0.1,thickness: 1,color: Colors.grey[200],),
SizedBox(height:5.0),
FlatButton(
color: Colors.lightGreen,
shape:
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
),
child:Text('Save',style: TextStyle(fontSize: 18.0,color:Colors.white),),
onPressed: () async {
var claims = claimsController.text;
var tax = taxController.text;
var reporttype = reporttypeController.text;
var merchant = merchantController.text;
var selectdate = selectdateController.text;
var description = descriptionController.text;
var amount = amountController.text;
var rsp = await claim(claims, amount, selectdate, merchant, tax, description, reporttype);
print(rsp);
if (rsp.containsKey('success') == true) {
print(rsp);
if (rsp['success'] == true) {
Fluttertoast.showToast(
msg: "saved",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.white,
textColor: Colors.green,
fontSize: 16.0
);
}
}
}
},
),
],
),
),
],
),
),
),
),
);
}
}
var result = jsonDecode(response.body);
return Expense.fromJson(result);
try changing it.
I'm trying to get JSON data from an API in my project. However, I came to an error and I'm completely stuck. I'm fairly new when it comes to deserializing JSON objects so appreciate your help on this.
This is my JSON file
{
"status": 200,
"data": [
{
"id": 1,
"title": "Down-sized 4thgeneration leverage",
"description": "Distinctio voluptas ea aliquid",
"address": "2755 Raul Estate\nWest Ervin, AZ 14265-2763",
"postcode": "42503-7193",
"phoneNumber": "387-842-0455x71431",
"latitude": "-60.964344",
"longitude": "-12.024244",
"image": {
"small": "http://lorempixel.com/200/200/cats/1/",
"medium": "http://lorempixel.com/400/400/cats/1/",
"large": "http://lorempixel.com/800/800/cats/1/"
}
},
{
"id": 2,
"title": "Optional intermediate orchestration",
"description": "Quia unde officiis ut eum",
"postcode": "06445-4404",
"phoneNumber": "103-350-9440x83127",
"latitude": "-84.165738",
"longitude": "62.221246",
"image": {
"small": "http://lorempixel.com/200/200/cats/2/",
"medium": "http://lorempixel.com/400/400/cats/2/",
"large": "http://lorempixel.com/800/800/cats/2/"
}
}
]
}
My part of my home file as follows:
body: Container(
child: Column(
children: [
///////// Future Builder checks the API service getusers() future method every refreshed time
Expanded(child: FutureBuilder(
future: apiService.getCars(),
builder: (context , snapshot){
if(snapshot.hasData)
{
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index){
////// User List item button
return GestureDetector(
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CarDetails(
car: snapshot.data[index].data[index].title,
)),
);
},
child:
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow( color: Colors.grey.withOpacity(0.3),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 5),
)
],
),
margin: EdgeInsets.symmetric(horizontal: 10 , vertical: 10),
padding: EdgeInsets.symmetric(horizontal: 10 , vertical: 10),
child: ListTile(
title: Text( snapshot.data[index].datalist[index].title , style: TextStyle(
fontSize: 18,color: Colors.black
),),
subtitle: Text( 'car Name', style: TextStyle(
fontSize: 18,color: Colors.black
),),
),
),
);
});
}else{
//////// Loading Circle from Spinkit Plugin
return Container(
child: Center(
child: SpinKitCircle(
color: Colors.orange,
),
),
);
}
},
))
],
) ,
),
This is my bean class(car.dart)
import 'dart:convert';
Car carFromJson(String str) => Car.fromJson(json.decode(str));
String carToJson(Car data) => json.encode(data.toJson());
class Car {
Car({
this.status,
this.data,
});
int status;
List<Datum> data;
factory Car.fromJson(Map<String, dynamic> json) => Car(
status: json["status"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
this.id,
this.title,
this.description,
this.address,
this.postcode,
this.phoneNumber,
this.latitude,
this.longitude,
this.image,
});
int id;
String title;
String description;
String address;
String postcode;
String phoneNumber;
String latitude;
String longitude;
Image image;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
title: json["title"],
description: json["description"],
address: json["address"],
postcode: json["postcode"],
phoneNumber: json["phoneNumber"],
latitude: json["latitude"],
longitude: json["longitude"],
image: Image.fromJson(json["image"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"description": description,
"address": address,
"postcode": postcode,
"phoneNumber": phoneNumber,
"latitude": latitude,
"longitude": longitude,
"image": image.toJson(),
};
}
class Image {
Image({
this.small,
this.medium,
this.large,
});
String small;
String medium;
String large;
factory Image.fromJson(Map<String, dynamic> json) => Image(
small: json["small"],
medium: json["medium"],
large: json["large"],
);
Map<String, dynamic> toJson() => {
"small": small,
"medium": medium,
"large": large,
};
}
This is my get cars method and the JSON response body
Future<List<Car>> getCars() async {
final response = await http.get(Uri.parse(apiUrl));
///// checking the status code is successful
if (response.statusCode == 200) {
return getCarList(response.body);
} else {
throw Exception('Unable to fetch data from API');
}
}
List<Car> getCarList(String responseBody) {
final parsed = json.decode(responseBody);
final List<dynamic> cars= parsed["data"];
return (cars.map((json) => Car.fromJson(json)).toList());
}
I am getting this error: "Unhandled Exception: NoSuchMethodError: The method 'map' was called on null."
Here is what my Debug Console says:
E/flutter ( 6246): [ERROR:flutter/lib/ui/ui_dart_state.cc(213)] Unhandled Exception: NoSuchMethodError: The method 'map' was called on null.
E/flutter ( 6246): Receiver: null
E/flutter ( 6246): Tried calling: map(Closure: (dynamic) => Datum)
E/flutter ( 6246): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:63:5)
E/flutter ( 6246): #1 new Car.fromJson (package:flutter_car_booking/car.dart:61:41)
E/flutter ( 6246): #2 RestAPIService.getCarList.<anonymous closure> (package:flutter_car_booking/api_service.dart:54:39)
E/flutter ( 6246): #3 MappedListIterable.elementAt (dart:_internal/iterable.dart:413:31)
E/flutter ( 6246): #4 ListIterator.moveNext (dart:_internal/iterable.dart:342:26)
E/flutter ( 6246): #5 new _GrowableList._ofEfficientLengthIterable (dart:core-patch/growable_array.dart:188:27)
E/flutter ( 6246): #6 new _GrowableList.of (dart:core-patch/growable_array.dart:150:28)
E/flutter ( 6246): #7 new List.of (dart:core-patch/array_patch.dart:50:28)
E/flutter ( 6246): #8 ListIterable.toList (dart:_internal/iterable.dart:213:44)
E/flutter ( 6246): #9 RestAPIService.getCarList (package:flutter_car_booking/api_service.dart:54:55)
E/flutter ( 6246): #10 RestAPIService.getCars (package:flutter_car_booking/api_service.dart:23:10)
E/flutter ( 6246): <asynchronous suspension>
The problem is you are passing respons.body["data"]["data"] to your Datum.fromJson() constructor but there is no such key in the json. on the other hand you are passing response.body["data"] to Car.fromJson() constructor which is a list of data that does not have "status" key in it.
Try changing your code as follows.
Future<Car> getCars() async {
final response = await http.get(Uri.parse(apiUrl));
///// checking the status code is successful
if (response.statusCode == 200) {
return getCarList(response.body);
} else {
throw Exception('Unable to fetch data from API');
}
}
Car getCarList(String responseBody) {
final Map<String, dynamic> cars= json.decode(responseBody);
return (Car.fromJson(cars));
}
and you Car class as follows.
class Car {
Car({
this.status,
this.data,
});
int status;
List<Datum> data;
factory Car.fromJson(Map<String, dynamic> json) => Car(
status: json["status"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
Change your build method as follows. because now you do not have a list from snapshot it is a Car object and it has the data property which has the list of Datum objects
body: Container(
child: Column(
children: [
///////// Future Builder checks the API service getusers() future method every refreshed time
Expanded(child: FutureBuilder<Car>(
future: apiService.getCars(),
builder: (BuildContext context ,AsyncSnapshot<Car> snapshot){
if(snapshot.hasData)
{
return ListView.builder(
itemCount: snapshot.data.data.length,
itemBuilder: (context, index){
////// User List item button
return GestureDetector(
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CarDetails(
car: snapshot.data.data[index].title,
)),
);
},
child:
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow( color: Colors.grey.withOpacity(0.3),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 5),
)
],
),
margin: EdgeInsets.symmetric(horizontal: 10 , vertical: 10),
padding: EdgeInsets.symmetric(horizontal: 10 , vertical: 10),
child: ListTile(
title: Text( snapshot.data.data[index].title , style: TextStyle(
fontSize: 18,color: Colors.black
),),
subtitle: Text( 'car Name', style: TextStyle(
fontSize: 18,color: Colors.black
),),
),
),
);
});
}else{
//////// Loading Circle from Spinkit Plugin
return Container(
child: Center(
child: SpinKitCircle(
color: Colors.orange,
),
),
);
}
},
))
],
) ,
),
I have an error when trying to parse my JSON and display it in the text, not as a listview.
Below is my JSON structure.
{
"status": "success",
"data": {
"id": 5,
"name": afri,
"class": 3c'
},
"message": "Success"
}
and this is my Future API async.
Future<Map> getData() async {
var response = await http.get(
'url');
return json.decode(response.body) as Map<String, dynamic>;
}
and this is my code to display the JSON.
Container(
child: FutureBuilder<Map>(
future: getData(),
builder: (context, snapshot) {
Map<String, dynamic> data = jsonDecode(snapshot.data["data"]);
return Card(
child: Container(
padding: EdgeInsets.all(8),
color: Colors.red,
child: Text(
data['port_website'],
style: TextStyle(color: Colors.white, fontSize: 24),
),
),
);
},
),
),
and when I'm trying to get the data, I got an error like this.
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String'
which code should I fix?
You can try to convert the runtime of data from _InternalLinkedHashMap to an exact list.
You can use List.form to achieve it.
final _data = List<dynamic>.from(
data.map<dynamic>(
(dynamic item) => item,
),
);
Edit 1
Worked for me. Try this
new Map<String, dynamic>.from(snapshot.value);