flutter problem: how to use dynamic data in chart? - flutter

I Have shared my api data which I stored in a list variable.
I want to show my that list data in chart.
How to do it?
I Have shared my api data which I stored in a list variable.
I want to show my that list data in chart.
How to do it?
this is my cart ui code
import 'package:bonanza_flutter/Constants/constants.dart';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class OverviewPage extends StatefulWidget {
const OverviewPage({Key? key})
: super(key: key);
#override
_OverviewPageState createState() => _OverviewPageState();
}
class _OverviewPageState extends State<OverviewPage> {
final List<ChartData> chartData = [
ChartData('Healthcare', 25.5, Color.fromRGBO(9, 0, 136, 1)),
ChartData('Education', 38, Color.fromRGBO(147, 0, 119, 1)),
ChartData('Power', 34, Color.fromRGBO(228, 0, 124, 1)),
ChartData('Manufacture', 52, greyColor),
ChartData('Agriculture', 52, greenColor),
ChartData('Services', 52, orangeColor),
ChartData('Others', 52, green2Color),
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.fromLTRB(20, 10, 20, 0),
child: Text(
"Sector Bifurcation",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
),
),
Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.fromLTRB(0, 0, 20, 0),
child: SfCircularChart(
legend: Legend(
isVisible: true,
width: "130",
legendItemBuilder: (String name, dynamic series,
dynamic point, int index) {
return Container(
width: 174,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(40),
color: point.color),
height: 15,
width: 15,
),
Padding(
padding: const EdgeInsets.fromLTRB(
9.0, 8, 15, 9),
child: Text(
point.x.toString(),
style: TextStyle(
color: blackColor,
fontSize: tSize13,
fontWeight: FontWeight.w500),
textAlign: TextAlign.left,
),
),
],
),
Padding(
padding: const EdgeInsets.fromLTRB(
9.0, 8, 15, 9),
child: Row(
children: [
Text(
point.y.toString(),
style: TextStyle(
color: blackColor,
fontSize: tSize13,
fontWeight: FontWeight.w500),
),
Text(
"%",
style: TextStyle(
color: blackColor,
fontSize: tSize13,
fontWeight: FontWeight.w500),
),
],
),
),
],
),
);
}),
series: <CircularSeries>[
DoughnutSeries<ChartData, String>(
dataSource: chartData,
pointColorMapper: (ChartData data, _) => data.color,
xValueMapper: (ChartData data, _) => data.x,
yValueMapper: (ChartData data, _) => data.y,
innerRadius: '60%'),
],
annotations: <CircularChartAnnotation>[
CircularChartAnnotation(
widget: Container(
child: Text(
'Sectors',
style: TextStyle(
fontSize: tSize16, fontWeight: FontWeight.w500),
)),
)
])),
],
),
],
),
),
);
}
}
class ChartData {
ChartData(this.x, this.y, [this.color]);
final String x;
final double y;
final Color? color;
}
This is my api data, I stored in list variable from api?
data = [ {
"name": "Others",
"weightage": "9.44"
},
{
"name": "INFORMATION TECHNOLOGY",
"weightage": "4.90"
},
{
"name": "BANKS",
"weightage": "22.72"
},
{
"name": "PHARMA",
"weightage": "5.09"
},
{
"name": "INDUSTRIAL MACHINERY",
"weightage": "2.57"
},
{
"name": "FINANCIAL SERVICES",
"weightage": "4.38"
},
{
"name": "FOOTWEAR",
"weightage": "1.75"
},
{
"name": "CHEMICALS",
"weightage": "4.50"
},
{
"name": "OIL EXPL. SERVICES",
"weightage": "2.12"
},
{
"name": "APPARELS & ACCESSORIES",
"weightage": "4.01"
},
{
"name": "Industrial Machinery",
"weightage": "1.80"
},
{
"name": "Miscellaneous",
"weightage": "20.16"
},
{
"name": "Plastics",
"weightage": "1.33"
},
{
"name": "Auto Ancil",
"weightage": "0.98"
},
{
"name": "CONSTRUCTION",
"weightage": "1.75"
},
{
"name": "FMCG",
"weightage": "1.21"
},
{
"name": "Other/Misc",
"weightage": "4.10"
},
{
"name": "Finance",
"weightage": "2.01"
},
{
"name": "TEXTILES",
"weightage": "2.81"
},
{
"name": "Pharmaceuticals",
"weightage": "2.01"
}];

Map data to List<ChartData>, which the widget already understands.
final chartData = data.map((item) => ChartData(
item['name']!,
double.parse(item['weightage']!)
)).toList();

Related

How to solve flutter page is not showing properly

I am currently working on an E-Commerce app. I have made my Homepage which shows the available products and a HomeDetailPage which shows the details of a single product when a user clicks on a particular product. Now the problem is my entire app is working finely in my Pixel-5 Emulator but the HomeDetailPage is not Working in my actual device when I install the app in my personal phone. I am currently using Samsung A50 as my actual device I dont understand what is wrong in this code
Here is the Code For Homepage:-
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_application_1/pages/homedetal.dart';
import 'package:flutter_application_1/products.dart';
class Homepage extends StatefulWidget {
const Homepage({Key? key}) : super(key: key);
#override
State<Homepage> createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
getdata() async {
var catalogdata = await rootBundle.loadString("assets/files/products.json");
var catalogjson = await jsonDecode(catalogdata);
var productdata = catalogjson["products"];
ProductsModel.productlist =
List.from(productdata).map<Item>((item) => Item.fromMap(item)).toList();
setState(() {});
}
#override
void initState() {
// TODO: implement initState
getdata();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
// key: ProductsModel.scaffoldKey,
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(right: 32.0, left: 32.0, top: 32.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'TonyShop',
style: TextStyle(
fontSize: 45,
color: Colors.deepPurple,
fontWeight: FontWeight.bold),
),
IconButton(
onPressed: () {
Navigator.pushNamed(context, "/login");
},
icon: Icon(
Icons.arrow_forward,
color: Colors.deepPurple,
))
],
),
),
Padding(
padding:
const EdgeInsets.only(right: 32.0, left: 32.0, bottom: 32.0),
child: Text(
'Trending products',
style: TextStyle(
fontSize: 20,
color: Colors.deepPurple,
fontWeight: FontWeight.bold),
),
),
// SizedBox(
// height: 20,
// ),
Expanded(
child: ListView.builder(
shrinkWrap: true,
physics: AlwaysScrollableScrollPhysics(),
itemCount: ProductsModel.productlist.length,
itemBuilder: (context, index) {
final catalog = ProductsModel.productlist[index];
return Material(
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
HomeDetailPage(singleitem: catalog),
));
},
child:
Itemwidget(item: ProductsModel.productlist[index])),
);
},
),
)
],
),
));
}
}
class Itemwidget extends StatefulWidget {
final Item item;
const Itemwidget({
Key? key,
required this.item,
}) : super(key: key);
#override
State<Itemwidget> createState() => _ItemwidgetState();
}
class _ItemwidgetState extends State<Itemwidget> {
#override
Widget build(BuildContext context) {
return Material(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Container(
decoration: BoxDecoration(
color: Color.fromARGB(255, 255, 255, 255),
borderRadius: BorderRadius.all(Radius.circular(20.0))),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Container(
height: 120,
width: 120,
child: Hero(
tag: Key(widget.item.id.toString()),
child: Image.network(widget.item.image)),
),
Padding(
padding: const EdgeInsets.only(left: 16.0),
child: Container(
width: 200,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.item.name,
style: TextStyle(
fontSize: 17, fontWeight: FontWeight.bold),
),
Container(
child: Text(
widget.item.desc,
style: TextStyle(
fontSize: 12, fontWeight: FontWeight.normal),
),
width: 150,
),
SizedBox(
height: 10,
),
ButtonBar(
buttonPadding: EdgeInsets.all(0.0),
alignment: MainAxisAlignment.spaceBetween,
children: [
Text(
widget.item.price.toString(),
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold),
),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomeDetailPage(
singleitem: widget.item)));
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Color.fromRGBO(
0,
0,
0,
1,
)),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(16.0)))),
child: Text(
"Buy",
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold),
),
)
],
)
],
),
),
)
],
),
),
),
),
);
}
}
And Here is my Code for HomeDetailPage:-
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_application_1/pages/home.dart';
import 'package:flutter_application_1/products.dart';
class HomeDetailPage extends StatefulWidget {
const HomeDetailPage({
Key? key,
required this.singleitem,
}) : super(key: key);
final Item singleitem;
#override
State<HomeDetailPage> createState() => _HomeDetailPageState();
}
class _HomeDetailPageState extends State<HomeDetailPage> {
Future<bool> _previousroute() {
// important trick to handle backbutton press;
return Future(() => Navigator.canPop(context));
}
#override
Widget build(BuildContext context) {
// Variables for getting the height and width of the screen
double h = MediaQuery.of(context).size.height;
double w = MediaQuery.of(context).size.width;
return WillPopScope(
onWillPop: () => _previousroute(),
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
shadowColor: Colors.white,
elevation: 0,
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
color: Colors.black,
onPressed: () {
Navigator.pop(context);
},
)),
// key: ProductsModel.scaffoldKey,
body: Container(
height: h,
child: Flexible(
fit: FlexFit.tight,
child: SingleChildScrollView(
padding: EdgeInsets.all(0.0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipPath(
clipper: Clipper(),
child: Container(
decoration: BoxDecoration(
color: Color.fromARGB(255, 240, 240, 245),
),
child: Padding(
padding: const EdgeInsets.all(32.0),
child: Hero(
tag: Key(widget.singleitem.id.toString()),
child: Image.network(widget.singleitem.image)),
),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
widget.singleitem.name,
style: TextStyle(
color: Colors.black,
fontSize: 30,
fontWeight: FontWeight.bold),
),
],
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
widget.singleitem.desc,
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.normal),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.only(left: 4.0, right: 4.0),
child: Container(
width: w,
// box decoration does not work with button
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(32.0)),
child: ElevatedButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return Container(
child: AlertDialog(
actions: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Your Order Is On The Way",
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold),
),
),
Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: () {
// Used to create ok button
Navigator.of(context).pop();
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(
Color.fromRGBO(
0,
0,
0,
1,
)),
shape: MaterialStateProperty
.all(RoundedRectangleBorder(
borderRadius:
BorderRadius
.circular(
16.0)))),
child: Text(
"Ok",
style: TextStyle(
fontSize: 20,
fontWeight:
FontWeight.bold),
),
),
)
],
)
],
));
});
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Color.fromRGBO(
0,
0,
0,
1,
)),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
))),
child: Text(
"Buy",
style: TextStyle(
color: Colors.white,
fontSize: 25,
fontWeight: FontWeight.bold),
),
),
),
),
)
],
),
),
),
),
),
);
}
}
class Clipper extends CustomClipper<Path> {
#override
Path getClip(Size size) {
// TODO: implement getClip
var path = new Path();
// fixed or unchanged points of the container
path.lineTo(0, 0);
path.lineTo(size.width, 0);
path.lineTo(size.width, size.height - 20);
path.quadraticBezierTo(
//point creating the curve radius
size.width / 2,
size.height + 20,
// starting point of the curve
0,
size.height - 20);
return path;
}
#override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
// TODO: implement shouldReclip
return false;
}
}
Here is my Products model class
import 'package:flutter/material.dart';
class ProductsModel {
static List productlist = [];
static final GlobalKey<ScaffoldState> scaffoldKey =
GlobalKey<ScaffoldState>();
}
class Item {
late final int id;
late final String name;
late final String desc;
late final int price;
late final String color;
late final String image;
Item({
required this.id,
required this.name,
required this.desc,
required this.price,
required this.color,
required this.image,
});
factory Item.fromMap(map) {
return Item(
id: map["id"],
name: map["name"],
desc: map["desc"],
price: map["price"],
color: map["color"],
image: map["image"]);
}
}
In case that if you want to try this yourself Here is my dummy product.json file code for you:-
{
"products": [
{
"id": 1,
"name": "iPhone 12 Pro",
"desc": "Apple iPhone 12th generation",
"price": 999,
"color": "#33505a",
"image": "https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/iphone-12-pro-blue-hero?wid=940&hei=1112&fmt=png-alpha&qlt=80&.v=1604021661000"
},
{
"id": 2,
"name": "Pixel 5",
"desc": "Google Pixel phone 5th generation",
"price": 699,
"color": "#00ac51",
"image": "https://www.telstra.com.au/content/dam/tcom/lego/2020/plans-devices/mobiles/google-pixel-5/shared-google-pixel-5-black-05-900x1200.png"
},
{
"id": 3,
"name": "M1 Macbook Air",
"desc": "Apple Macbook air with apple silicon",
"price": 1099,
"color": "#e0bfae",
"image": "https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP825/macbookair.png"
},
{
"id": 4,
"name": "Playstation 5",
"desc": "Sony Playstation 5th generation",
"price": 500,
"color": "#544ee4",
"image": "https://i1.wp.com/freepngimages.com/wp-content/uploads/2020/07/Playstation-5-games-console-transparent-background-png-image.png?fit=1000%2C1000"
},
{
"id": 5,
"name": "Airpods Pro",
"desc": "Apple Aipods Pro 1st generation",
"price": 200,
"color": "#e3e4e9",
"image": "https://crdms.images.consumerreports.org/c_lfill,w_598/prod/products/cr/models/400116-wireless-portable-headphones-apple-airpods-pro-10009323.png"
},
{
"id": 6,
"name": "iPad Pro",
"desc": "Apple iPad Pro 2020 edition",
"price": 799,
"color": "#f73984",
"image": "https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/ipad-pro-12-select-wifi-silver-202003_FMT_WHH?wid=940&hei=1112&fmt=png-alpha&qlt=80&.v=1583551131102"
},
{
"id": 7,
"name": "Galaxy S21 Ultra",
"desc": "Samsung Galaxy S21 Ultra 2021 edition",
"price": 1299,
"color": "#1c1c1c",
"image": "https://lh3.googleusercontent.com/qRQPjHrhRVIs-xnfNSyiPXOH2vH97ylMacgbTKebqJtRfNH3LlYo8pN-5igsLDWUH62tGl5zNpTsl5xd8SprzGmXoCEmWFOi2-2cQVGS-r3PaRXHt62DmJHq-jrYX0UQvWZ9BA=s800-c"
},
{
"id": 8,
"name": "Galaxy S21",
"desc": "Samsung Galaxy S21 2021 edition",
"price": 899,
"color": "#7c95eb",
"image": "https://images.samsung.com/is/image/samsung/p6pim/za/galaxy-s21/gallery/za-clear-cover-galaxy-s21-5g-ef-qg991ttegww-363168624?$720_576_PNG$"
}
]
}
In my emulator it looks like this Emulator Image
In my Device it looks like this Device Image
It's because of expanded widget in HomeDetailsScreen, you can use Flexible instead of expanded like that:
Flexible(
fit: FlexFit.tight,
child: ...,
);

User Interface Design Overflowing while rendering data items in List in Flutter

I have a UI design that looks a little messed up at the moment and I've gone totally blank as to what more I could do to fix this. All I do right now is just keep staring at the code only to figure out no solution at all. The idea is to render a list with the data received from the server response. You would find the code and the JSON response below. Please note that the reason behind using the for loops is to render the data that is nested inside of the list in the response.
The issue:
As you can tell, Every image should have the text and the prices written next to them and not the way it is now. Then on the next line, the next item needs to get rendered in the same way, and so on. I have marked the exact code with a comment.
My code:
class RecentItems extends StatefulWidget {
RecentItemsState createState() => RecentItemsState();
}
class RecentItemsState extends State<RecentItems> {
bool isLoading = true;
// bool isExpanded = false;
#override
void initState() {
// TODO: implement initState
Provider.of<OrderHistoryProvider>(context, listen: false)
.getOrderHistory()
.then((_) {
setState(() {
isLoading = false;
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
final height = MediaQuery.of(context).size.height;
final width = MediaQuery.of(context).size.width;
final tabLayout = width > 600;
final largeLayout = width > 350 && width < 600;
// final textScaleFactor = MediaQuery.of(context).textScaleFactor * 1.2;
final provider = Provider.of<OrderHistoryProvider>(context).orderHistory;
// TODO: implement build
return Padding(
padding: EdgeInsets.only(left: width * 0.04, right: width * 0.04),
child: isLoading
? const Center(
child: CircularProgressIndicator(
color: Colors.green,
),
)
: Container(
width: double.infinity,
// height: height * 0.7,
// color: Colors.red,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Recent Orders',
// // textScaleFactor: textScaleFactor,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: tabLayout
? 25
: largeLayout
? 17
: 12),
),
InkWell(
onTap: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => PendingOrders())),
child: Text(
'View All',
// // textScaleFactor: textScaleFactor,
style: TextStyle(
color: Colors.green,
fontWeight: FontWeight.bold,
fontSize: tabLayout
? 18
: largeLayout
? 14
: 10),
),
)
],
),
SizedBox(height: height * 0.04),
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) => Padding(
padding: EdgeInsets.only(
left: width * 0.02, right: width * 0.02),
child: Column(
children: [
Container(
width: double.infinity,
height: tabLayout
? height * 0.14
: largeLayout
? height * 0.1
: height * 0.12,
padding: EdgeInsets.fromLTRB(width * 0.01,
height * 0.005, width * 0.02, height * 0.005),
margin: provider['data'][index]['order_details']
['isExpanded'] ==
true
? const EdgeInsets.only(bottom: 0)
: EdgeInsets.only(bottom: height * 0.04),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: provider['data'][index]
['order_details']['isExpanded'] ==
true
? const BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20))
: BorderRadius.circular(20),
boxShadow: const [
BoxShadow(
color: Colors.grey,
blurRadius: 5,
offset: Offset(0, 2))
]),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
margin: EdgeInsets.only(left: width * 0.02),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
provider['data'][index]['order_details']
['order_number'],
// // textScaleFactor: textScaleFactor,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: tabLayout
? 25
: largeLayout
? 17
: 12),
),
SizedBox(height: height * 0.01),
Text(
provider['data'][index]['order_details']
['created_at'],
// // textScaleFactor: textScaleFactor,
style: TextStyle(
color: Colors.grey[600],
fontWeight: FontWeight.bold,
fontSize: tabLayout
? 18
: largeLayout
? 12
: 8),
)
],
),
),
SizedBox(
width: tabLayout
? width * 0.3
: largeLayout
? width * 0.1
: width * 0.25),
Row(
children: [
FittedBox(
fit: BoxFit.scaleDown,
child: Text(
'₹${provider['data'][index]['order_details']['grand_total']}',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: tabLayout
? 50
: largeLayout
? 17
: 12),
),
),
InkWell(
onTap: () {
print(
'length: ${provider['data'][index]['order_products'].length}');
print(
'isExpanded: ${provider['data'][index]['order_details']['isExpanded']}');
setState(() {
provider['data'][index]
['order_details']
['isExpanded'] =
!provider['data'][index]
['order_details']
['isExpanded'];
});
},
child: Icon(!provider['data'][index]
['order_details']['isExpanded']
? Icons.arrow_drop_down
: Icons.arrow_drop_up))
],
)
],
),
),
//The code that's causing this
if (provider['data'][index]['order_details']
['isExpanded'] ==
true)
Container(
width: double.infinity,
margin: EdgeInsets.only(bottom: height * 0.04),
padding: const EdgeInsets.all(10),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(20)),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 5,
offset: Offset(0, 2))
]),
child: Container(
width: double.infinity,
height: height * 0.2,
padding: const EdgeInsets.all(5),
color: Colors.red,
child: ListView(
children: [
Row(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
for (int itemDetails = 0;
itemDetails <
provider['data'][index]
['order_products']
.length;
itemDetails++)
Container(
width: width * 0.2,
height: height * 0.06,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(10),
border: Border.all(
color: Colors.green,
width: 2)),
child: ClipRRect(
borderRadius:
BorderRadius.circular(10),
child: Image.network(
'http://54.80.135.220${provider['data'][index]['order_products'][itemDetails]['product']['main_image']}',
fit: BoxFit.cover,
),
),
),
SizedBox(width: width * 0.02),
Column(
children: [
for (var itemDetails
in provider['data'][index]
['order_products'])
Text(
'${itemDetails['product']['name']} ${itemDetails['product']['weight']}${itemDetails['product']['uom']['short_name']}',
style: const TextStyle(
fontWeight:
FontWeight.bold),
),
for (int itemDetails = 0;
itemDetails <
provider['data'][index]
['order_products']
.length;
itemDetails++)
Text(
'₹${provider['data'][index]['order_products'][itemDetails]['price']} x ${provider['data'][index]['order_products'][itemDetails]['quantity']} ')
],
)
],
),
],
),
),
)
],
),
),
itemCount: provider['data'].length > 3
? 3
: provider['data'].length,
)
],
),
),
);
}
}
The JSON Response:
{
"status": "success",
"message": "Order list fetched successfully",
"data": [
{
"order_details": {
"id": 14,
"address": {
"id": 14,
"name": "Rachhel Sekh2",
"contact_number": "9641355412",
"postcode": "700079",
"address_line": "48 Tarunsen Gupta Sarani Road 1",
"locality": "Dum Dum 1",
"city": "Kolkata 1",
"state": "West Bengal 1",
"save_address_as": "Home",
"is_default": true,
"map_lat": "22.643824",
"map_lng": "88.426776",
"user": 14
},
"created_at": "2022-06-13T13:06:22.901003+05:30",
"updated_at": "2022-06-13T13:06:22.930737+05:30",
"order_number": "ORD4726409566",
"price": "1740.00",
"shipping_charge": "0.00",
"tax": "71.60",
"grand_total": "1630.44",
"offer_code": "KOL96",
"offer_discount": "181.16",
"payment_method": "COD",
"payment_status": "Pending",
"order_status": "Order Placed",
"user": 14,
"delivery_exe": null
},
"order_products": [
{
"id": 20,
"price": "160.00",
"quantity": 7,
"total_price": "1120.00",
"product": {
"id": 13,
"created_at": "2022-06-13T00:52:17.284597+05:30",
"updated_at": "2022-06-13T00:52:17.284649+05:30",
"name": "Oats",
"short_description": "Oats",
"description": "Oaaaaaaatsssssss",
"status": "in_stock",
"weight": "1",
"qty": 20,
"price": 160.0,
"tax": "5.00",
"main_image": "/media/product_module/product/image_picker2440066848872026571.jpg",
"soft_delete": false,
"category": {
"id": 3,
"created_at": "2022-06-10T13:03:51.772459+05:30",
"updated_at": "2022-06-10T13:03:51.772503+05:30",
"name": "Grocery and Staples",
"categoryImage": "/media/product_module/category/41619-7-groceries-free-download-image-thumb.png",
"active": true
},
"sizes": {
"id": 4,
"created_at": "2022-06-02T13:48:05.957406+05:30",
"updated_at": "2022-06-02T13:48:05.957440+05:30",
"size": "large"
},
"brand_name": null,
"uom": {
"id": 1,
"created_at": "2022-06-02T13:49:10.746284+05:30",
"updated_at": "2022-06-02T13:49:10.746317+05:30",
"name": "Kilogram",
"short_name": "Kg"
}
}
},
{
"id": 21,
"price": "100.00",
"quantity": 3,
"total_price": "300.00",
"product": {
"id": 2,
"created_at": "2022-06-05T22:55:36.543639+05:30",
"updated_at": "2022-06-13T00:41:32.279753+05:30",
"name": "Apple",
"short_description": "Apllleeee",
"description": "Appleeee Le Looooooo",
"status": "out_of_stock",
"weight": "200",
"qty": 30,
"price": 100.0,
"tax": "2.00",
"main_image": "/media/product_module/product/image_picker1124916014311738168.jpg",
"soft_delete": false,
"category": {
"id": 1,
"created_at": "2022-06-02T13:42:24.973439+05:30",
"updated_at": "2022-06-02T13:57:04.123793+05:30",
"name": "Fruits and Vegetables",
"categoryImage": "/media/product_module/category/png-transparent-graphy-vegetable-fruit-basket-of-vegetables-natu_lvwqkfm.png",
"active": true
},
"sizes": {
"id": 3,
"created_at": "2022-06-02T13:47:55.172720+05:30",
"updated_at": "2022-06-02T13:47:55.172755+05:30",
"size": "medium"
},
"brand_name": null,
"uom": {
"id": 2,
"created_at": "2022-06-02T13:49:27.640236+05:30",
"updated_at": "2022-06-02T13:50:18.553700+05:30",
"name": "Gram",
"short_name": "gm"
}
}
},
{
"id": 22,
"price": "160.00",
"quantity": 2,
"total_price": "320.00",
"product": {
"id": 12,
"created_at": "2022-06-07T19:39:58.277106+05:30",
"updated_at": "2022-06-13T13:26:17.541253+05:30",
"name": "Mango",
"short_description": "Banginapalli",
"description": "fresh and juicy",
"status": "out_of_stock",
"weight": "4",
"qty": 35,
"price": 160.0,
"tax": "3.00",
"main_image": "/media/product_module/product/image_picker5640335828307412875.jpg",
"soft_delete": false,
"category": {
"id": 1,
"created_at": "2022-06-02T13:42:24.973439+05:30",
"updated_at": "2022-06-02T13:57:04.123793+05:30",
"name": "Fruits and Vegetables",
"categoryImage": "/media/product_module/category/png-transparent-graphy-vegetable-fruit-basket-of-vegetables-natu_lvwqkfm.png",
"active": true
},
"sizes": {
"id": 3,
"created_at": "2022-06-02T13:47:55.172720+05:30",
"updated_at": "2022-06-02T13:47:55.172755+05:30",
"size": "medium"
},
"brand_name": {
"id": 1,
"created_at": "2022-06-02T13:46:44.445296+05:30",
"updated_at": "2022-06-02T13:46:44.445328+05:30",
"name": "NA"
},
"uom": {
"id": 1,
"created_at": "2022-06-02T13:49:10.746284+05:30",
"updated_at": "2022-06-02T13:49:10.746317+05:30",
"name": "Kilogram",
"short_name": "Kg"
}
}
}
]
}
]
}
Any help would be appreciated!
Try using ListView.builder to wrap your content instead of using for loop

output data from API to List or Card on Flutter

import 'dart:convert';
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:image_picker/image_picker.dart';
import 'package:http/http.dart' as http;
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
State<HomeScreen> createState() => _HomeState();
}
class _HomeState extends State<HomeScreen> {
File? imageFile;
#override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints:
BoxConstraints(minHeight: viewportConstraints.maxHeight),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Загрузите фото, на котором видны Ваши продукты. К примеру это может быть фото холодильника',
style: TextStyle(
color: Color(0xffffffff),
fontSize: 20,
decoration: TextDecoration.none,
fontWeight: FontWeight.w500,
fontFamily: 'Palanquin'),
),
if (imageFile != null)
Container(
width: 300,
height: 300,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.grey,
image: DecorationImage(
image: FileImage(imageFile!), fit: BoxFit.cover),
//border: Border.all(width: 8, color: Colors.black),
borderRadius: BorderRadius.circular(15.0),
),
)
else
Container(
width: 300,
height: 300,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Color(0xffa7c8fd),
//border: Border.all(width: 8, color: Colors.black12),
borderRadius: BorderRadius.circular(15.0),
),
child: const Text(
'Image should appear here',
style: TextStyle(
color: Color(0xffffffff),
fontSize: 30,
decoration: TextDecoration.none,
fontWeight: FontWeight.w500,
fontFamily: 'Palanquin'),
),
),
const SizedBox(
height: 20,
),
Row(
children: [
Expanded(
child: ElevatedButton(
onPressed: () => getImage(source: ImageSource.camera),
child: const Text('Capture Image',
style: TextStyle(fontSize: 18))),
),
const SizedBox(
width: 20,
),
Expanded(
child: ElevatedButton(
onPressed: () =>
getImage(source: ImageSource.gallery),
child: const Text('Select Image',
style: TextStyle(fontSize: 18))),
),
],
),
const SizedBox(
height: 30,
),
ElevatedButton(
child: Text("Перейти к списку рецептов"),
onPressed: () => Upload(imageFile!),
//color: Color(0xff24997f),
//textColor: Colors.white,
//shape: RoundedRectangleBorder(
//borderRadius: BorderRadius.all(Radius.circular(25))),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 15, vertical: 4),
height: 100,
child: Card(
child: FutureBuilder(
future: Upload(imageFile!),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container()
}//I don't know what's next.
},
)
)
)
],
),
),
);
},
);
}
void getImage({required ImageSource source}) async {
final file = await ImagePicker().pickImage(
source: source,
maxWidth: 300,
maxHeight: 300,
imageQuality: 70 //0 - 100
);
if (file?.path != null) {
setState(() {
imageFile = File(file!.path);
});
}
}
Future Upload(File imageFile) async {
var headers = {
'Authorization': 'Bearer dc14a17ca4e34b79e0cf0773ac83df914e7e15f7'
};
var request = http.MultipartRequest(
'POST',
Uri.parse(
'https://api.logmeal.es/v2/image/recognition/complete/v1.0?language=eng'));
request.files
.add(await http.MultipartFile.fromPath('image', imageFile.path));
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
var s = (await response.stream.bytesToString());
var body = jsonDecode(s)['recognition_results'] as List;
var valuesApi = body.map((e) => e['name']).toList();
} else {
print(response.reasonPhrase);
}
}
}
Hi all, I was trying to connect the LogMeal api. The user had to upload a picture, then the picture is sent to the api and the products from the picture are returned to the card. After connecting, I can't get the data to ListView or Card. image_picker helped me to take the user's picture, then in Upload(imageFile) I passed the data from the api
The JSON is as follows:
{
"foodFamily": [
{
"id": 8,
"name": "vegetables/legumes",
"prob": 0.5361328125
}
],
"foodType": [
{
"id": 1,
"name": "food"
},
{
"id": 1,
"name": "food"
},
{
"id": 1,
"name": "food"
},
{
"id": 2,
"name": "ingredients"
},
{
"id": 1,
"name": "food"
},
{
"id": 1,
"name": "food"
}
],
"imageId": 1362287,
"model_versions": {
"drinks": "v1.0",
"foodType": "v1.0",
"foodgroups": "v1.0",
"foodrec": "v1.0",
"ingredients": "v1.0"
},
"recognition_results": [
{
"id": 875,
"name": "cereals",
"prob": 0.10022780299186707,
"subclasses": []
},
{
"id": 703,
"name": "fruit salad",
"prob": 0.036238476634025574,
"subclasses": []
},
{
"id": 957,
"name": "lacasitos",
"prob": 0.03444254398345947,
"subclasses": []
},
{
"id": 1224,
"name": "berries",
"prob": 0.027621030807495117,
"subclasses": [
{
"id": 1245,
"name": "raspberry",
"prob": 0.003658294677734375
}
]
},
{
"id": 2140,
"name": "fruit flan",
"prob": 0.02529066801071167,
"subclasses": []
},
{
"id": 391,
"name": "charcuterie board",
"prob": 0.021760307252407074,
"subclasses": []
}
]
}

How to display the value chosen?

The value that I chose from the DropdownMenuItem (eg: Malaysia (+06) ), the chosen value will be displayed, however, when I navigate back or proceed to other interfaces, it will disappear.
Problem:
How to make the chosen value maintained at the dropdown button box?
Is it any solution to solve the problem?
Below is my code segment inside showModalBottomSheet:
String _selectedCountryCode;
List jsonResult = List();
loadJsonData() async {
String data = await rootBundle.loadString('assets/country_code.json');
jsonResult = json.decode(data);
print(jsonResult);
}
#override
void initState() {
super.initState();
loadJsonData();
phoneController = TextEditingController();
}
Widget Part
Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
TextButton(
onPressed: () {
_showModalPhoneWidget();
},
child: Text(
"Request OTP", style: TextStyle(
color: const Color(0xff002aff),
fontSize: 15,
),
),)
],
)
_showModalPhoneWidget method part
_showModalPhoneWidget() {
showModalBottomSheet(
backgroundColor: Colors.green,
context: context,
isDismissible: true,
//transitionAnimationController: Duration(milliseconds: 400),
builder: (context) {
return StatefulBuilder(
builder: (context, setStateSTB) => ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
topRight: Radius.circular(10.0)),
child: Container(
height: 250,
color: Colors.white,
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10.0),
child: Text(
"Update Phone",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
),
Padding(
padding: EdgeInsets.only(top: 20.0, left: 10.0),
child: Row(
children: <Widget>[
Text(
"Tel No",
style:
TextStyle(color: Colors.black, fontSize: 15.0),
),
Text(
"*",
style: TextStyle(color: Colors.red, fontSize: 15.0),
),
],
),
),
Container(
margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
height: 50.0,
width: double.infinity,
decoration: BoxDecoration(
border: Border.all(color: const Color(0xffededed))),
child: Stack(
children: <Widget>[
Row(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 5.0, left: 5.0),
height: 40.0,
width: 100.0,
child: DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: false,
child: DropdownButton(
// child: DropdownButton<Map<String, String>>(
isExpanded: true,
value: _selectedCountryCode,
selectedItemBuilder: (BuildContext context)
{
return jsonResult.map<Widget>((element) {
return Text("${element['dial_code']}", textAlign: TextAlign.center);
}).toList();
},
items: jsonResult.map((element) {
return DropdownMenuItem(
child: Text("${element['name']} (${element['dial_code']})", overflow: TextOverflow.clip, maxLines: 1,),
value: element['dial_code'],
);
}).toList(),
onChanged: (val) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
//* to change on dialog
setStateSTB(() {
_selectedCountryCode = val;
prefs.setString('_selectedCountryCode', _selectedCountryCode);
print('select code: $_selectedCountryCode' );
});
//* to change on StateLevel
setState(() {
_selectedCountryCode = val;
prefs.setString('_selectedCountryCode', _selectedCountryCode);
});
},
),
),
),
),
// if(_isEditingText)
Container(
width: 120,
height: 40,
child: TextField(
controller: phoneController,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
], // Only numbers can be entered
textAlign: TextAlign.center,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Tel No. Ex:0133333333',
),
onSubmitted: (newPhoneNo) {
setState(() {
initialText = newPhoneNo;
_isEditingText = false;
});
},
),
),
Container(
height: 40,
width: 100,
child: InkWell(
onTap: () {
setState(() {
_isEditingText = true;
});
},
),
),
],
)
],
),
),
Container(
margin: EdgeInsets.all(20.0),
child: ButtonTheme(
minWidth: double.infinity,
height: 50,
child: OutlineButton(
child: Text("Continue",
style: TextStyle(color: Colors.amber, fontSize: 16)),
borderSide: BorderSide(
color: Colors.amber,
),
highlightElevation: 10.0,
onPressed: () {
},
),
),
),
],
),
),
),
);
});
}
and this is my local JSON data:
[
{
"name": "Malaysia",
"dial_code": "+60",
"code": "MY"
},
{
"name": "Afghanistan",
"dial_code": "+93",
"code": "AF"
},
{
"name": "Aland Islands",
"dial_code": "+358",
"code": "AX"
},
{
"name": "Albania",
"dial_code": "+355",
"code": "AL"
},
{
"name": "Algeria",
"dial_code": "+213",
"code": "DZ"
},
{
"name": "AmericanSamoa",
"dial_code": "+1684",
"code": "AS"
},
{
"name": "Andorra",
"dial_code": "+376",
"code": "AD"
},
{
"name": "Angola",
"dial_code": "+244",
"code": "AO"
},
{
"name": "Anguilla",
"dial_code": "+1264",
"code": "AI"
},
{
"name": "Antarctica",
"dial_code": "+672",
"code": "AQ"
},
{
"name": "Antigua and Barbuda",
"dial_code": "+1268",
"code": "AG"
},
{
"name": "Argentina",
"dial_code": "+54",
"code": "AR"
},
{
"name": "Armenia",
"dial_code": "+374",
"code": "AM"
},
{
"name": "Aruba",
"dial_code": "+297",
"code": "AW"
},
{
"name": "Australia",
"dial_code": "+61",
"code": "AU"
},
{
"name": "Austria",
"dial_code": "+43",
"code": "AT"
},
{
"name": "Azerbaijan",
"dial_code": "+994",
"code": "AZ"
},
{
"name": "Bahamas",
"dial_code": "+1242",
"code": "BS"
},
{
"name": "Bahrain",
"dial_code": "+973",
"code": "BH"
},
{
"name": "Bangladesh",
"dial_code": "+880",
"code": "BD"
},
{
"name": "Barbados",
"dial_code": "+1246",
"code": "BB"
},
{
"name": "Belarus",
"dial_code": "+375",
"code": "BY"
},
{
"name": "Belgium",
"dial_code": "+32",
"code": "BE"
},
]
For problem 1 you can have the Map for DropdownMenuItem. While showing only name and dial_code you can set child like
items: jsonResult.map((element) {
return DropdownMenuItem(
child: Text(
"${element['name']} ${element['dial_code']}"),
value: element,
);
}).toList(),
For problem 2 updating state on dialog needs to use StatefulBuilder and use its setstate to update on dialog, prefer renaming this.
return StatefulBuilder(
builder: (context, setStateSTB) => ClipRRect(
......
onChanged: (_selectedCountryCode) {
//* to change on dialog
setStateSTB(() {
_defaultCountryCode = _selectedCountryCode;
});
//* to change on StateLevel
setState(() {
_defaultCountryCode = _selectedCountryCode;
});
},
Update the issue was on loadJsonData()
Future<void> loadJsonData() async {
///
String data = await rootBundle.loadString('assets/country_code.json');
final jsonString = jsonDecode(data) as List;
final item = jsonString.map((e) {
return {
'name': e['name'] as String,
'dial_code': e['dial_code'] as String,
'code': e['code'] as String,
};
}).toList();
setState(() {
jsonResult = item;
});
}
Full snippet
class _TFTState extends State<TFT> {
Map<String, String>? _defaultCountryCode;
late List<Map<String, String>> jsonResult;
#override
void initState() {
super.initState();
loadJsonData();
}
Future<void> loadJsonData() async {
///
String data = await rootBundle.loadString('assets/country_code.json');
final jsonString = jsonDecode(data) as List;
final item = jsonString.map((e) {
return {
'name': e['name'] as String,
'dial_code': e['dial_code'] as String,
'code': e['code'] as String,
};
}).toList();
setState(() {
jsonResult = item;
});
}
final phoneController = TextEditingController();
_showModalPhoneWidget() {
showModalBottomSheet(
backgroundColor: Colors.green,
context: context,
isDismissible: true,
//transitionAnimationController: Duration(milliseconds: 400),
builder: (context) {
return StatefulBuilder(
builder: (context, setStateSTB) => ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
topRight: Radius.circular(10.0)),
child: Container(
height: 250,
color: Colors.white,
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10.0),
child: Text(
"Update Phone",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
),
Padding(
padding: EdgeInsets.only(top: 20.0, left: 10.0),
child: Row(
children: <Widget>[
Text(
"Tel No",
style:
TextStyle(color: Colors.black, fontSize: 15.0),
),
Text(
"*",
style: TextStyle(color: Colors.red, fontSize: 15.0),
),
],
),
),
Container(
margin:
EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
height: 50.0,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: const Color(0xffededed))),
child: Row(
children: <Widget>[
DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: true,
child: DropdownButton<Map<String, String>>(
value: _defaultCountryCode,
hint: Text("Hint textOn null"),
items: jsonResult.map((element) {
return DropdownMenuItem(
child: Text(
"${element['name']} ${element['dial_code']}"),
value: element,
);
}).toList(),
onChanged: (_selectedCountryCode) {
//* to change on dialog
setStateSTB(() {
_defaultCountryCode = _selectedCountryCode;
});
//* to change on StateLevel
setState(() {
_defaultCountryCode = _selectedCountryCode;
});
},
),
),
),
Container(
width: 250,
height: 40,
child: TextField(
controller: phoneController,
textAlign: TextAlign.start,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Tel No. Ex:0133333333',
),
),
),
],
),
),
Container(
margin: EdgeInsets.all(20.0),
child: ButtonTheme(
minWidth: double.infinity,
height: 50,
child: OutlineButton(
child: Text("Continue",
style:
TextStyle(color: Colors.amber, fontSize: 16)),
borderSide: BorderSide(
color: Colors.amber,
),
highlightElevation: 10.0,
onPressed: () {},
),
),
),
],
),
),
),
);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
ElevatedButton(
onPressed: () {
// json loaded on initState
print(jsonResult.length);
_showModalPhoneWidget();
},
child: Text("s"),
)
],
),
);
}
}

flutter Error: The method '[]' was called on null. Receiver: null Tried calling: []("product")

when I clicking on my cart icon then open my cartpage.dart in this page my data not showing and give error but when i am using fast reload flutter page then that data is comming.
How to solve it please help me.
error=>
The method '[]' was called on null. Receiver: null Tried calling:
This is my cartPage.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:hospital/CartPage/components/cartCard.dart';
import 'package:hospital/CartPage/components/priceDetailsCard.dart';
import 'package:hospital/constant.dart';
import 'package:hospital/customApiVariable.dart';
import 'package:http/http.dart' as http;
class Cartpage extends StatefulWidget {
#override
_CartpageState createState() => _CartpageState();
}
class _CartpageState extends State<Cartpage> {
var response;
var addToCartApi;
#override
void initState() {
super.initState();
fetchData();
}
fetchData() async {
var api = Uri.parse(
'$ecommerceBaseUrl/addToCartApi.php?a2rTokenKey=$a2rTokenKey&action=addToCartList&uid=${var_uid}');
response = await http.get(api);
print("Carousel" + response.body);
addToCartApi = jsonDecode(response.body);
print('addToCartApi' + addToCartApi['total'].toString());
// store in variable
totalOfferPrice = addToCartApi['total']['grandTotalOfferPrice'].toString();
totalPrice = addToCartApi['total']['grandTotalPrice'].toString();
totalPriceAfterOffer =
addToCartApi['total']['grandTotalPriceAfterOffer'].toString();
deliveryName = addToCartApi['total']['deliveryName'];
deliveryCharge = addToCartApi['total']['deliveryCharge'].toString();
total_num = addToCartApi['total']['num'].toString();
setState(() {});
}
// List allItems = CartRepo().getAllCartItems();
#override
Widget build(BuildContext context) {
final _media = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
backgroundColor: kGreen,
title: Text("My Cart"),
),
body: Stack(
children: [
Container(
decoration: BoxDecoration(color: Color(0xFFeeeeee)),
height: _media.height,
width: _media.width,
),
ListView(
shrinkWrap: true,
children: <Widget>[
CartCard(user_id: var_uid),
PriceDetailsCard(totalItem: addToCartApi['total']),
SizedBox(
height: 100,
)
],
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: _media.width,
height: _media.height * .08,
decoration: BoxDecoration(color: Colors.white, boxShadow: [
BoxShadow(color: Colors.black87, blurRadius: 5.0),
BoxShadow(color: Colors.white, blurRadius: 10.0),
]),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"\u20B9 ${totalPriceAfterOffer}",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 20),
),
Text(
"View price details",
style: TextStyle(
color: Colors.blueGrey,
fontWeight: FontWeight.bold),
)
],
),
),
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: Container(
width: _media.width * .4,
child: RaisedButton(
onPressed: () {},
color: kGreen,
child: Text(
"PLACE ORDER",
style: TextStyle(color: Colors.white),
),
)),
),
],
),
),
)
],
));
}
}
This is CartCard.dart page
import 'dart:convert';
import 'package:flutter/material.dart';
// import 'package:hospital/FourthDelete/fourth_delete.dart';
// import 'package:hospital/FourthSection/MedicineProductList/medicine_product_list.dart';
import 'package:hospital/ProductDetailsPage/product_detailPage.dart';
import 'package:hospital/SecondSection/Medicine/medicine_page.dart';
import 'package:hospital/constant.dart';
import 'package:hospital/customApiVariable.dart';
import 'package:http/http.dart' as http;
class CartCard extends StatefulWidget {
final user_id;
const CartCard({Key key, this.user_id}) : super(key: key);
#override
_CartCardState createState() => _CartCardState();
}
class _CartCardState extends State<CartCard> {
var response;
//this drinks call from api
var cartCardApi;
#override
void initState() {
// TODO: implement initState
//
super.initState();
// for loading
fetchData(widget.user_id);
}
fetchData(auth_uid) async {
// var api = Uri.parse(
// 'https://www.a2rstore.in/oceonicApi/ecommerce/v2/api/categoryApi.php?a2rTokenKey=carpet1234');
// var api = Uri.parse('$baseUrl/productCatApi.php?a2rTokenKey=$a2rTokenKey');
var api = Uri.parse(
// '$ecommerceBaseUrl/addToCartApi.php?a2rTokenKey=$a2rTokenKey&action=addToCartList&uid=${widget.auth_uid}');
'$ecommerceBaseUrl/addToCartApi.php?a2rTokenKey=$a2rTokenKey&action=addToCartList&uid=${widget.user_id}');
// 'https://www.a2rstore.in/oceonicApi/ecommerce/v1/api/productSubCatApi.php?a2rTokenKey=a2rhos1234&pcat=60c461f032f2a');
response = await http.get(
api,
);
print("cartCardApi " + api.toString());
print("cartCardbody " + response.body);
// in double quotes drink is key value of json
cartCardApi = jsonDecode(response.body);
print("cartCardApi " + cartCardApi.toString());
return cartCardApi['product'];
// setState(() {});
}
String quantity = "1";
#override
Widget build(BuildContext context) {
final _media = MediaQuery.of(context).size;
return ListView.builder(
// itemCount: categoryApi.length.clamp(0, 3),//THis is for showed minimun length of item listview.builder flutter
itemCount: cartCardApi['product'].length,
scrollDirection: Axis.vertical,
physics: ScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
var cartCard = cartCardApi['product'][index];
return Container(
height: _media.height * .4,
child: Card(
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(
left: 10.0, top: 10, bottom: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: _media.width * .6,
child: Text(
// widget.item.desc,
cartCard["productName"],
maxLines: 2,
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.w500),
overflow: TextOverflow.ellipsis,
),
),
SizedBox(
height: 5,
),
Text(
// widget.item.quantity,
' Quantity ${cartCard['orderQuantity']}',
style:
TextStyle(color: Colors.grey, fontSize: 14),
),
SizedBox(
height: 10,
),
Row(
children: <Widget>[
Text(
"Seller: ",
style: TextStyle(
color: Colors.grey, fontSize: 14),
),
Icon(
Icons.check_circle,
color: Colors.grey,
size: 15,
)
],
),
SizedBox(
height: 15,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: <Widget>[
Text(
"\u20B9 " +
cartCard[
'productPriceAfterOffer'],
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 23),
),
Padding(
padding:
const EdgeInsets.only(left: 10.0),
child: Text(
"\u20B9 " +
cartCard['productRealPrice'],
style: TextStyle(
color: Colors.grey,
decoration:
TextDecoration.lineThrough),
),
),
SizedBox(
width: 5,
),
Text(
'40' + "%off",
style: TextStyle(
color: Colors.green,
fontSize: 13,
fontWeight: FontWeight.w600),
)
],
),
SizedBox(
height: 10,
),
Text(
"2 offers available",
style: TextStyle(
color: Colors.green,
fontSize: 13,
fontWeight: FontWeight.w600),
)
],
)
],
)
],
),
),
Padding(
padding: const EdgeInsets.only(
top: 10.0, right: 8, bottom: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
color: Colors.white,
child: Row(
children: <Widget>[
Container(
width: _media.width * .3,
height: _media.height * .2,
child: Image.network(
// 'https://media.gettyimages.com/photos/woman-using-meal-delivery-service-through-mobile-app-picture-id1160735344?k=6&m=1160735344&s=612x612&w=0&h=tYEeckvNDyAoyUEfUeCii_29p_pBum_BVHKiUrGbjYY=',
cartCard['pImgImg'],
fit: BoxFit.cover,
),
)
],
),
),
Row(
children: <Widget>[
Text(
"Qty:",
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(
width: 10,
),
DropdownButton<String>(
value: quantity,
items: <String>["1", "2", "3", "4", "5"]
.map((String value) =>
DropdownMenuItem<String>(
value: value, child: Text(value)))
.toList(),
onChanged: (_value) {
setState(() {
quantity = _value;
});
},
)
],
),
],
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
height: _media.height * .08,
width: _media.width * .4875,
child: RaisedButton(
onPressed: () {},
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.favorite,
size: 15,
color: Colors.grey,
),
SizedBox(
width: 5,
),
Text(
"SAVE FOR LATER",
style: TextStyle(fontSize: 15),
)
],
),
),
),
Container(
height: _media.height * .08,
width: _media.width * .4875,
child: RaisedButton(
onPressed: () {},
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.delete,
size: 15,
color: Colors.grey,
),
SizedBox(
width: 5,
),
Text(
"REMOVE",
style: TextStyle(fontSize: 15),
)
],
),
),
),
],
)
],
),
),
);
});
}
}
This is my json data
{
"product": [
{
"plistId": "60c71ed46839f",
"plistPriceId": "",
"uid": "60daaedd3b9f8751161",
"orderQuantity": "1",
"date": "2021-07-06",
"productName": "MUKTI CHURNA",
"productCode": "499",
"productlink": "detail.php?pListName=MUKTI CHURNA&plistId=60c71ed46839f",
"productRealPrice": "1112",
"productPriceAfterOffer": 1110,
"productOfferAmountMulOrdrQuantity": 0,
"quantity": "1 p",
"pImgImg": "http:\/\/a2rstore.com\/inventory\/images\/product_images\/product-Mukti-Churan-600x600.jpg",
"subTotalRealPrice": 1110,
"subTotalofferPrice": 0,
"subTotalPriceAfterOffer": 1110
},
{
"plistId": "60cacee2ee4ff",
"plistPriceId": "",
"uid": "60daaedd3b9f8751161",
"orderQuantity": "1",
"date": "2021-07-06",
"productName": " PAIN CALM OIL",
"productCode": "504",
"productlink": "detail.php?pListName= PAIN CALM OIL&plistId=60cacee2ee4ff",
"productRealPrice": "123",
"productPriceAfterOffer": "123",
"productOfferAmountMulOrdrQuantity": 0,
"quantity": "1 p",
"pImgImg": "http:\/\/a2rstore.com\/inventory\/images\/product_images\/product-Oil-pulling-ff-600x600.jpg",
"subTotalRealPrice": 123,
"subTotalofferPrice": 0,
"subTotalPriceAfterOffer": 123
},
{
"plistId": "60cacee2ee4ff",
"plistPriceId": "",
"uid": "60daaedd3b9f8751161",
"orderQuantity": "3",
"date": "2021-07-06",
"productName": " PAIN CALM OIL",
"productCode": "504",
"productlink": "detail.php?pListName= PAIN CALM OIL&plistId=60cacee2ee4ff",
"productRealPrice": "123",
"productPriceAfterOffer": "123",
"productOfferAmountMulOrdrQuantity": 0,
"quantity": "1 p",
"pImgImg": "http:\/\/a2rstore.com\/inventory\/images\/product_images\/product-Oil-pulling-ff-600x600.jpg",
"subTotalRealPrice": 369,
"subTotalofferPrice": 0,
"subTotalPriceAfterOffer": 369
},
{
"plistId": "60cacee2ee4ff",
"plistPriceId": "",
"uid": "60daaedd3b9f8751161",
"orderQuantity": "3",
"date": "2021-07-06",
"productName": " PAIN CALM OIL",
"productCode": "504",
"productlink": "detail.php?pListName= PAIN CALM OIL&plistId=60cacee2ee4ff",
"productRealPrice": "123",
"productPriceAfterOffer": "123",
"productOfferAmountMulOrdrQuantity": 0,
"quantity": "1 p",
"pImgImg": "http:\/\/a2rstore.com\/inventory\/images\/product_images\/product-Oil-pulling-ff-600x600.jpg",
"subTotalRealPrice": 369,
"subTotalofferPrice": 0,
"subTotalPriceAfterOffer": 369
},
{
"plistId": "60cacee2ee4ff",
"plistPriceId": "",
"uid": "60daaedd3b9f8751161",
"orderQuantity": "1",
"date": "2021-07-06",
"productName": " PAIN CALM OIL",
"productCode": "504",
"productlink": "detail.php?pListName= PAIN CALM OIL&plistId=60cacee2ee4ff",
"productRealPrice": "123",
"productPriceAfterOffer": "123",
"productOfferAmountMulOrdrQuantity": 0,
"quantity": "1 p",
"pImgImg": "http:\/\/a2rstore.com\/inventory\/images\/product_images\/product-Oil-pulling-ff-600x600.jpg",
"subTotalRealPrice": 123,
"subTotalofferPrice": 0,
"subTotalPriceAfterOffer": 123
},
{
"plistId": "60cacee2ee4ff",
"plistPriceId": "",
"uid": "60daaedd3b9f8751161",
"orderQuantity": "1",
"date": "2021-07-06",
"productName": " PAIN CALM OIL",
"productCode": "504",
"productlink": "detail.php?pListName= PAIN CALM OIL&plistId=60cacee2ee4ff",
"productRealPrice": "123",
"productPriceAfterOffer": "123",
"productOfferAmountMulOrdrQuantity": 0,
"quantity": "1 p",
"pImgImg": "http:\/\/a2rstore.com\/inventory\/images\/product_images\/product-Oil-pulling-ff-600x600.jpg",
"subTotalRealPrice": 123,
"subTotalofferPrice": 0,
"subTotalPriceAfterOffer": 123
}
],
"total": {
"grandTotalOfferPrice": 0,
"grandTotalPrice": 123,
"grandTotalPriceAfterOffer": 123,
"deliveryName": "Shipping Charge",
"deliveryCharge": "Free",
"num": 6
}
}
According to the error your cartCardApi is null before you are accessing it in the ListView.
If it'a is an API call use FutureBuilder to handle all the asynchronous calls like showing loading, error when there is an error from api and the ui if its success.
Otherwise make cartCardApi as an empty list from before.
So that when you call setState the new list is updated and ui gets the new list.
Looks like your cartCardApi is null somewhere when you are trying to fetch the "product" value.
Seems the way you are trying to fetch data from products is wrong. Try to print the full JSON from response and print each individual item to see the correct value.
This is why JSON formatting is preferred where you can create a model class for the response values, and map the response values to predefined keys in the model class and then use that model class to populate values in UI.
Avoids these types of errors
https://medium.com/flutter-community/parsing-complex-json-in-flutter-747c46655f51