I want to get the sum total of the price of all the products in a list of cards with data from firestore - flutter

I want to get the sum total of the price of all the products in a list of cards with data from firestore and i don't how to do that on flutter.
This is the where i show the cards and where i want to show the total price too:
class ShopListPage extends StatelessWidget {
const ShopListPage({super.key});
Stream<List<ShopList>> readProducts() => FirebaseFirestore.instance
.collection('shoplist')
.orderBy('price')
.snapshots()
.map((snapshot) =>
snapshot.docs.map((doc) => ShopList.fromJson(doc.data())).toList());
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).colorScheme.background,
body: StreamBuilder<List<ShopList>>(
stream: readProducts(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Algo ha ocurrido! ${snapshot.error}');
} else if (snapshot.hasData) {
final shoplist = snapshot.data!;
return ListView(
children: shoplist
.map((p) => BuildListCards(shopList: p))
.toList());
} else {
return const Center(child: CircularProgressIndicator());
}
}),
floatingActionButton: FloatingActionButton(
child: const Icon(
Icons.paid,
),
onPressed: () {},
),
);
}
}
The BuildListCard Class: here is where i show the price individually
class BuildListCards extends StatelessWidget {
final ShopList shopList;
const BuildListCards({Key? key, required this.shopList}) : super(key: key);
#override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.all(8),
clipBehavior: Clip.hardEdge,
child: ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 80),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Image(
image: NetworkImage(shopList.imageUrl),
fit: BoxFit.cover,
),
Padding(
padding: const EdgeInsets.all(8),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(shopList.name),
Text('Precio: ${shopList.price}\$'),
Text('Cantidad: ${shopList.quantity}')
],
),
),
const Spacer(),
Padding(
padding: const EdgeInsets.fromLTRB(0, 25, 8, 0),
child: ElevatedButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(
const Color(0xFFFFFFFF),
),
backgroundColor: MaterialStateProperty.all<Color>(
const Color(0xFF6750A4),
),
),
onPressed: () => showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) => AlertDialog(
title: Text(
'¿Desea eliminar el producto ${shopList.name} de la base de datos?',
textAlign: TextAlign.center,
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Cancelar')),
TextButton(
onPressed: () {
final docShopList = FirebaseFirestore.instance
.collection('shoplist')
.doc(shopList.id);
docShopList.delete();
Navigator.pop(context);
},
child: const Text('Eliminar')),
],
),
),
child: const Text(
'Eliminar',
),
),
),
],
),
),
);
}
}
i want to calculate the sum total of the price, i use shoplist.price to show the price

Related

can't refresh listview after update and delete flutter

Hello I'm a new flutter user, here I'm trying to complete CRUD but when I finish adding, editing, and deleting the listview page it can't be refreshed immediately. When I re-open the new page can be refreshed. Do you think friends here can solve my problem? Thank you good friends can help me.
Here's my source code snippet
Here is my source code snippet :
listnasabah.dart
class ListNasabah {
ApiService apiService;
ListNasabah({this.apiService});
void getNasabah() {
apiService.getNasabah().then((nasabah) {
print(nasabah);
});
}
Widget createViewList() {
return SafeArea(
child: FutureBuilder(
future: apiService.getNasabah(),
builder: (BuildContext context, AsyncSnapshot<List<Nasabah>> snapshot) {
if (snapshot.hasError) {
return Center(
child: Text(
'Something wrong with message: ${snapshot.error.toString()}',
textAlign: TextAlign.center,
),
);
} else if (snapshot.connectionState == ConnectionState.done) {
List<Nasabah> nasabah = snapshot.data;
return nasabahListView(nasabah);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
Widget nasabahListView(List<Nasabah> listnasabah) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (context, index) {
Nasabah nasabah = listnasabah[index];
return Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
nasabah.nama_debitur,
style: Theme.of(context).textTheme.bodyText1,
),
Text(nasabah.alamat),
Text(nasabah.no_ktp),
Text(nasabah.no_telp),
Text(nasabah.no_selular),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FlatButton(
onPressed: () {
apiService
.deleteNasabah(nasabah.id)
.whenComplete(() {
Alert(
context: context,
type: AlertType.success,
title: "Sukses",
desc: "Data berhasil dihapus",
buttons: [
DialogButton(
child: Text(
"OK",
style: TextStyle(
color: Colors.white, fontSize: 20),
),
onPressed: () {
Navigator.pop(context);
},
width: 120,
)
],
).show();
});
},
child: Text(
"Hapus",
style: TextStyle(color: Colors.red),
),
),
TextButton(
onPressed: () async {
var result = await Navigator.push(context,
MaterialPageRoute(builder: (context) {
return FormAddNasabah(nasabah: nasabah);
}));
},
child: Text(
'Edit',
style: TextStyle(color: Colors.blue),
),
),
],
)
],
),
),
),
);
},
itemCount: listnasabah.length,
),
);
}
}
datanasabah.dart
class DataNasabah extends StatefulWidget {
DataNasabah({Key key}) : super(key: key);
final String title = "Data Nasabah";
#override
_DataNasabahState createState() => _DataNasabahState();
}
class _DataNasabahState extends State<DataNasabah> {
ApiService apiService;
ListNasabah _listNasabah;
#override
void initState() {
super.initState();
apiService = ApiService();
_listNasabah = new ListNasabah(apiService: apiService);
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldState,
appBar: AppBar(
title: Text(
'Data Nasabah',
style: TextStyle(color: Colors.white),
),
actions: <Widget>[
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FormAddNasabah(),
),
);
},
child: Padding(
padding: const EdgeInsets.only(right: 16.0),
child: Icon(
Icons.add,
color: Colors.white,
),
),
)
],
),
body: _listNasabah.createViewList(),
);
}
}
If it's getting refreshed after you come back from another page then its problem with rendering UI as you are not using any state management here. You can check state management in flutter, I would suggest to use Provider(https://pub.dev/packages/provider).
For stateful widget you can use setState function.

Using TabBar like filter

i'm trying to make a Tabbar that appear in a new page when the search icon in pressed. The code works fine but i don't know how to implement this tabbar. I want to use the tabbar for splitting the search info, each icon has to show only specific info.
I guess each icon has a specific list?
This is my search_tool.dart this appear when the icon button at the main page is pressed
[EDIT] Now the result is shown correctly, but when I press the search box to write the error message contained in buildSuggestion always appears, instead it should only show the list with the relative records and if something not belonging to that category is searched then it must give the error message
import 'package:flutter/material.dart';
import 'package:solaris/lista_data.dart';
import 'constants.dart';
class LinkItemsSearch extends SearchDelegate<LinkItem>{
#override
PreferredSizeWidget buildBottom(BuildContext context) {
return PreferredSize(
child: Container(
alignment: Alignment.center,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Apps';
this.showResults(context);
},
child: Text('Apps'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Movies';
this.showResults(context);
},
child: Text('Movies'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Games';
this.showResults(context);
},
child: Text('Games'),
),
),
],
),
),
),
preferredSize: Size.fromHeight(60),
);
}
#override
List<Widget> buildActions(BuildContext context) {
return [IconButton(icon: Icon(Icons.clear),onPressed: () { query=""; },)];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(onPressed: () { Navigator.pop(context); }, icon: Icon(Icons.arrow_back),);
}
#override
Widget buildResults(BuildContext context) {
var mylist = loadLinkItem().where((p) => p.description.contains(query)).toList();
return Container(
color: blue,
child: ListView.builder(
itemCount: mylist.length,
itemBuilder: (context,index){
final LinkItem listitem = mylist[index];
return Container(
color: blue,
child: ListTile(
title:InkWell(
onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget> [
Text(listitem.title, style: TextStyle(color: Colors.white),),
Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
Divider(color: white,),
],
),
),
),
);
}
),
);
}
#override
Widget buildSuggestions(BuildContext context) {
final mylist = query.isEmpty? loadLinkItem():loadLinkItem().where((p) => p.description.contains(RegExp(query, caseSensitive: false))).toList();
return mylist.isEmpty?
Container(
color: red,
child: Center(child: Text('No Result Found . . .', style: TextStyle(color: Colors.white,fontSize: 20,))),
):Container(
color: blue,
child: ListView.builder(
itemCount: mylist.length,
itemBuilder: (context,index){
final LinkItem listitem = mylist[index];
return Container(
color: blue,
child: ListTile(onTap: (){ showResults(context);},
title:InkWell(
onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget> [
Text(listitem.title, style: TextStyle(color: Colors.white),),
Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
Divider(color: white,),
],
),
),
),
);
}
),
);
}
}
Search icon
IconButton(onPressed:(){
showSearch(context: context, delegate: LinkItemsSearch());
}, icon: Icon(Icons.search),),
List
class LinkItem{
final String title;
final String description;
final link;
LinkItem({
required this.title,
required this.description,
required this.link,
});
}
List<LinkItem> loadLinkItem(){
var link = <LinkItem>[
LinkItem(
title: 'Title1',
description: 'Apps',
link: Title1(),
),LinkItem(
title: 'Title2',
description: 'Movies',
link: Title2(),
),LinkItem(
title: 'Title3',
description: 'Games',
link: Title3(),
),
];
return link;
}
You can override the buildBottom method in your LinkItemsSearch:
#override
PreferredSizeWidget buildBottom(BuildContext context) {
return PreferredSize(
child: Container(
alignment: Alignment.center,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Apps';
mylist = loadLinkItem()
.where((p) => p.description.contains(query))
.toList();
this.showResults(context);
},
child: Text('Apps'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Movies';
mylist = loadLinkItem()
.where((p) => p.description.contains(query))
.toList();
this.showResults(context);
},
child: Text('Movies'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Games';
mylist = loadLinkItem()
.where((p) => p.description.contains(query))
.toList();
this.showResults(context);
},
child: Text('Games'),
),
),
],
),
),
),
preferredSize: Size.fromHeight(60),
);
}
For this to work, you have to create myList on the top of your LinkItemsSearch and reuse it when filtering everywhere.
Also, I just updated loadLinkItem method to have some input for filtering:
List<LinkItem> loadLinkItem() {
var link = <LinkItem>[
LinkItem(
title: 'Title1',
description: 'Movies',
link: '',
),
LinkItem(
title: 'Title2',
description: 'Games',
link: '',
),
LinkItem(
title: 'Title3',
description: 'Apps',
link: '',
),
];
return link;
}
Of course, I have not completely matched your style, so I did not style buttons as you need it, you might higher bottom bar than 60 as I used. I also have not attached any on press handlers since I am not sure what should they do, but it looks as it is expected: https://i.stack.imgur.com/osUkt.png
I wrapped them with a Column and SingleChildScrollView in case you have more of those items and they need to be scrollable: https://i.stack.imgur.com/FyWVX.png
You can even add some conditions in cases when you don't need this bottom bar to be displayed and in that case, you can just return null from the buildBottom method.
FIX
import 'package:flutter/material.dart';
import 'package:solaris/lista_data.dart';
import 'constants.dart';
class LinkItemsSearch extends SearchDelegate<LinkItem>{
#override
PreferredSizeWidget buildBottom(BuildContext context) {
return PreferredSize(
child: Container(
alignment: Alignment.center,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Apps';
this.showResults(context);
},
child: Text('Apps'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Movies';
this.showResults(context);
},
child: Text('Movies'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Games';
this.showResults(context);
},
child: Text('Games'),
),
),
],
),
),
),
preferredSize: Size.fromHeight(60),
);
}
#override
List<Widget> buildActions(BuildContext context) {
return [IconButton(icon: Icon(Icons.clear),onPressed: () { query=""; },)];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(onPressed: () { Navigator.pop(context); }, icon: Icon(Icons.arrow_back),);
}
#override
Widget buildResults(BuildContext context) {
var mylist = loadLinkItem().where((p) => p.description.contains(query)).toList();
return Container(
color: blue,
child: ListView.builder(
itemCount: mylist.length,
itemBuilder: (context,index){
final LinkItem listitem = mylist[index];
return Container(
color: blue,
child: ListTile(
title:InkWell(
onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget> [
Text(listitem.title, style: TextStyle(color: Colors.white),),
Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
Divider(color: white,),
],
),
),
),
);
}
),
);
}
#override
Widget buildSuggestions(BuildContext context) {
final mylist = query.isEmpty? loadLinkItem():loadLinkItem().where((p) => p.description.contains(RegExp(query, caseSensitive: false))).toList();
return mylist.isEmpty?
Container(
color: red,
child: Center(child: Text('No Result Found . . .', style: TextStyle(color: Colors.white,fontSize: 20,))),
):Container(
color: blue,
child: ListView.builder(
itemCount: mylist.length,
itemBuilder: (context,index){
final LinkItem listitem = mylist[index];
return Container(
color: blue,
child: ListTile(onTap: (){ showResults(context);},
title:InkWell(
onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget> [
Text(listitem.title, style: TextStyle(color: Colors.white),),
Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
Divider(color: white,),
],
),
),
),
);
}
),
);
}
}

How to sent data into two different class within a file using navigator in flutter

I am lost my direction. Can Someone help me how can I send my data from the first page to the second page using Navigator? There are two types of class that exist in the destination file which are a stateful widget and a stateless widget. I am trying to send data from the first page using navigator:
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context)=> new restaurantLISTVIEW(category :categoriesList[index].name)));
The restaurantLISTVIEW is a stateful class on the second page. How can I share the data with the stateless class within the same file?
My full code on the first page:
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:phpfood/restaurantlist.dart';
//import 'globals.dart' as globals;
import 'custom_textW.dart';
class Category {
final String name;
final String image;
Category({#required this.name, #required this.image});
}
List<Category> categoriesList = [
Category(name: "Breakfast", image: "nasilemak.png"),
//Category(name: "Kuih", image: "kuih.png"),
Category(name: "Lunch", image: "lunch.png"),
//Category(name: "Minum Petang", image: "mnmptg.png"),
Category(name: "Dinner", image: "mknmlm.png"),
//Category(name: "Minum Malam", image: "mnmmlm.png"),
//Category(name: "Minuman", image: "air.png"),
];
class Categories extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
height: 120,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categoriesList.length,
itemBuilder: (_, index) {
return Padding(
padding: const EdgeInsets.only(left: 28.0, top: 8),
child: Column(
children: <Widget>[
Container(
decoration: BoxDecoration(color: Colors.white, boxShadow: [
BoxShadow(
color: Colors.red[200], offset: Offset(4, 6), blurRadius: 20)
]),
//tambah di sini kalau nk gesture
child: InkWell(
//onTap: ()=> Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context)=> new SarapanPagi(),)),
onTap: (){
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context)=> new restaurantLISTVIEW(category :categoriesList[index].name)));
},
/*{
if(categoriesList[index].name == "Breakfast"){
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context)=> new restaurantLISTVIEW(category: 'breakfast')));
//Navigator.of(context).push(MaterialPageRoute<void>(builder: (context) => restaurantLISTVIEW(category: 'breakfast',),),);
}
else if(categoriesList[index].name == "Lunch"){
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context)=> new restaurantLISTVIEW()));
}
else if(categoriesList[index].name == "Dinner"){
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context)=> new restaurantLISTVIEW()));
}
},*/
child: Image.asset(
"images/${categoriesList[index].image}",
width: 100,
),
),
),
SizedBox(
height: 5,
),
CustomText(
text: categoriesList[index].name,
size: 17,
colors: Colors.black,
)
],
),
);
},
),
);
}
}
My full code on the second page:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
import 'breakfast.dart';
// ignore: camel_case_types
class restaurantLISTVIEW extends StatefulWidget {
restaurantLISTVIEW({this.category});
final String category;
#override
_restaurantLISTVIEWState createState() => _restaurantLISTVIEWState();
}
// ignore: camel_case_types
class _restaurantLISTVIEWState extends State<restaurantLISTVIEW> {
Future<List> getData() async{
var url = 'http://10.0.2.2/foodsystem/restaurantlist.php';
var data = {'product_type': 'xde pape ppon saje nk hantar value'};
var response = await http.post(url, body: json.encode(data));
//final response= await http.get("http://10.0.2.2/foodsystem/getdata.php");
return json.decode(response.body);}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.black),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
//Text("Restaurant's Owner Page"),
Text('${widget.category}', textAlign: TextAlign.center, style: TextStyle(fontSize: 25, fontWeight: FontWeight.w700), ),
],
),
centerTitle: false,
//automaticallyImplyLeading: false,
),
body:
Padding(
padding: const EdgeInsets.only(bottom: 20, left: 5, right: 5),
child: Column(
children: [
SizedBox(height: 30,),
Container(
//decoration: BoxDecoration(border: Border.all(color: Colors.black, width: 4), borderRadius: BorderRadius.circular(15)),
height: 600,
child: FutureBuilder<List>(
future: getData(),
builder: (context, snapshot){
if(snapshot.hasError) print(snapshot.error);
return snapshot.hasData ?
ItemList(list: snapshot.data,) :
Center(child: CircularProgressIndicator(),);
},
),
),
FloatingActionButton(
onPressed: (){
return showDialog(
context: context,
builder: (context){
return AlertDialog(
content: Text(
'${widget.category}'
),
);
},
);
},
),
SizedBox(height: 10,),
],
),
),
);
}
}
class ItemList extends StatelessWidget {
final List list;
final String category;
ItemList({this.list, this.category});
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(
//color: Colors.red.shade100,
height: 600,
child: ListView.builder(
itemCount: list==null ? 0 : list.length,
itemBuilder: (context, i){
return new Container(
height: 200,
child: new GestureDetector(
onTap: ()
{Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context)=> new SarapanPagi(list: list, index: i, category: category,)));},
/*{
if(category == "Breakfast"){
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context)=> new SarapanPagi(list: list, index: i, category: category,)));
}
},*/
child: new Card(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
FloatingActionButton(
onPressed: (){
return showDialog(
context: context,
builder: (context){
return AlertDialog(
content: Text(
'$category hellp'
),
);
},
);
},
),
Row(
children: [
Container(
constraints: BoxConstraints(minWidth: 180, maxWidth: 180),
child:
Column(
children: [
Text(list[i]["restaurant_name"], style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold), textAlign: TextAlign.center,),
Text("Restaurant ID: ${list[i]["restaurant_id"]}", style: TextStyle(fontSize: 20,), textAlign: TextAlign.center,),
],
),
),
Padding(
padding: const EdgeInsets.only(left :20.0),
child: Container(
constraints: BoxConstraints(minWidth: 150, maxWidth: 300),
child:
SizedBox(
width: 50,
child: Column(
children: [
Text("SSM: ${list[i]["restaurant_ssm"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 15),),
Text("Phone: ${list[i]["restaurant_phone"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 15),),
Text("Address: ${list[i]["restaurant_address"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 15),),
],
),
),
),
),
],
),
Row(
children: [
],
),
],
),
),
),
);
},
),
),
);
}
}
As you can see in the stateless class, I am already calling the value from the first page, but it returns null because there is nothing forwarded to that class.
The problem is that you did not share the name data for the ItemList class through the category parameter:
make the following correction:
builder: (context, snapshot){
if(snapshot.hasError) print(snapshot.error);
return snapshot.hasData ?
ItemList(list: snapshot.data, category: widget.category) :
Center(child: CircularProgressIndicator(),);
},
a tip is to use the #required notation in the widget constructor so as not to forget to fill in the named parameters. Example:
class ItemList extends StatelessWidget {
final List list;
final String category;
ItemList({#required this.list, #required this.category});
#override
Widget build(BuildContext context) {
return Container();
}
}

how to use widget value from stateful into stateless

I am having a stuck on transferring the value from the second page to the third page using the value pass from the first page. when I am trying to use the usual way that I am used to calling the data in the stateful widget, it returns an error on undefined.
class restaurantLISTVIEW extends StatefulWidget {
restaurantLISTVIEW({this.category});
final String category;
#override
_restaurantLISTVIEWState createState() => _restaurantLISTVIEWState();
}
within extends state:(working)
FloatingActionButton(
onPressed: (){
return showDialog(
context: context,
builder: (context){
return AlertDialog(
content: Text(
'${widget.category}'
),
);
},
);
},),
error on extends stateless widget, return null: (not working)
onTap: ()
{
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context)=> new SarapanPagi(list: list, index: i, category: category)));
}
within extends stateless:(not working)
FloatingActionButton(
onPressed: (){
return showDialog(
context: context,
builder: (context){
return AlertDialog(
content: Text(
'$category hellp'
),
);
},
);
},),
The whole code on the second page:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as HTTP;
import 'breakfast.dart';
// ignore: camel_case_types
class restaurantLISTVIEW extends StatefulWidget {
restaurantLISTVIEW({this.category});
final String category;
#override
_restaurantLISTVIEWState createState() => _restaurantLISTVIEWState();
}
// ignore: camel_case_types
class _restaurantLISTVIEWState extends State<restaurantLISTVIEW> {
Future<List> getData() async{
var url = 'http://10.0.2.2/foodsystem/restaurantlist.php';
var data = {'product_type': 'xde pape ppon saje nk hantar value'};
var response = await http.post(url, body: json.encode(data));
//final response= await http.get("http://10.0.2.2/foodsystem/getdata.php");
return json.decode(response.body);}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.black),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
//Text("Restaurant's Owner Page"),
Text('${widget.category}', textAlign: TextAlign.center, style: TextStyle(fontSize: 25, fontWeight: FontWeight.w700), ),
],
),
centerTitle: false,
//automaticallyImplyLeading: false,
),
body:
Padding(
padding: const EdgeInsets.only(bottom: 20, left: 5, right: 5),
child: Column(
children: [
SizedBox(height: 30,),
Container(
//decoration: BoxDecoration(border: Border.all(color: Colors.black, width: 4), borderRadius: BorderRadius.circular(15)),
height: 600,
child: FutureBuilder<List>(
future: getData(),
builder: (context, snapshot){
if(snapshot.hasError) print(snapshot.error);
return snapshot.hasData ?
ItemList(list: snapshot.data,) :
Center(child: CircularProgressIndicator(),);
},
),
),
FloatingActionButton(
onPressed: (){
return showDialog(
context: context,
builder: (context){
return AlertDialog(
content: Text(
'${widget.category}'
),
);
},
);
},
),
SizedBox(height: 10,),
],
),
),
);
}
}
class ItemList extends StatelessWidget {
final List list;
final String category;
ItemList({this.list, this.category});
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(
//color: Colors.red.shade100,
height: 600,
child: ListView.builder(
itemCount: list==null ? 0 : list.length,
itemBuilder: (context, i){
return new Container(
height: 200,
child: new GestureDetector(
onTap: ()
{
if(widget.category == "Breakfast"){
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context)=> new SarapanPagi(list: list, index: i, category: category)));
}
},
child: new Card(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
constraints: BoxConstraints(minWidth: 180, maxWidth: 180),
child:
Column(
children: [
Text(list[i]["restaurant_name"], style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold), textAlign: TextAlign.center,),
Text("Restaurant ID: ${list[i]["restaurant_id"]}", style: TextStyle(fontSize: 20,), textAlign: TextAlign.center,),
],
),
),
Padding(
padding: const EdgeInsets.only(left :20.0),
child: Container(
constraints: BoxConstraints(minWidth: 150, maxWidth: 300),
child:
SizedBox(
width: 50,
child: Column(
children: [
Text("SSM: ${list[i]["restaurant_ssm"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 15),),
Text("Phone: ${list[i]["restaurant_phone"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 15),),
Text("Address: ${list[i]["restaurant_address"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 15),),
],
),
),
),
),
],
),
Row(
children: [
],
),
],
),
),
),
);
},
),
),
);
The whole code on the third page:
import 'dart:convert';
import 'package:http/http.dart' as HTTP;
import 'package:flutter/material.dart';
//import 'globals.dart' as globals;
class SarapanPagi extends StatefulWidget {
final List list;
final int index;
final String category;
SarapanPagi({this.index,this.list,this.category});
#override
_SarapanPagiState createState() => _SarapanPagiState();
}
class _SarapanPagiState extends State<SarapanPagi> {
Future<List> getData() async{
var url = 'http://10.0.2.2/foodsystem/breakfastlist.php';
var data = {
'product_type': 'Breakfast',
'product_owner': widget.list[widget.index]['restaurant_id'],
};
var response = await http.post(url, body: json.encode(data));
//final response= await http.get("http://10.0.2.2/foodsystem/getdata.php");
return json.decode(response.body);}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.black),
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
//Text("Restaurant's Owner Page"),
Text(widget.list[widget.index]['restaurant_name'], textAlign: TextAlign.center, style: TextStyle(fontWeight: FontWeight.w700), ),
],
),
centerTitle: false,
//automaticallyImplyLeading: false,
),
body:
Padding(
padding: const EdgeInsets.only(bottom: 20, left: 5, right: 5),
child: Column(
children: [
SizedBox(height: 30,),
Container(
//decoration: BoxDecoration(border: Border.all(color: Colors.black, width: 4), borderRadius: BorderRadius.circular(15)),
height: 600,
child: FutureBuilder<List>(
future: getData(),
builder: (context, snapshot){
if(snapshot.hasError) print(snapshot.error);
return snapshot.hasData ?
ItemList(list: snapshot.data,) :
Center(child: CircularProgressIndicator(),);
},
),
),
SizedBox(height: 10,),
],
),
),
);
}
}
class ItemList extends StatelessWidget {
final List list;
ItemList({this.list});
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(
//color: Colors.red.shade100,
height: 600,
child: ListView.builder(
itemCount: list==null ? 0 : list.length,
itemBuilder: (context, i){
return new Container(
height: 200,
child: new GestureDetector(
onTap: (){},
child: new Card(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
"images/${list[i]['image']}",
width: 150,
height: 150,
),
),
Padding(
padding: const EdgeInsets.only(left: 20.0, bottom: 0),
child:
Column(
children: [
Text(list[i]["product_name"], textAlign: TextAlign.center, style: TextStyle(fontSize: 30),),
Text("Price RM : ${list[i]["product_price"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 25),),
RaisedButton(
shape: RoundedRectangleBorder(borderRadius: new BorderRadius.circular(40.0)),
color: Colors.red.shade300,
child: Text("Add to Cart", style: TextStyle(fontWeight: FontWeight.bold),),
onPressed: (){},
)
],
),
),
],
),
/*ListTile(
title: Text(list[i]["product_name"], textAlign: TextAlign.center, style: TextStyle(fontSize: 30),),
leading:
Image.asset(
"images/${list[i]['image']}",
width: 100,
height: 100,
),
subtitle: Text("Price RM : ${list[i]["product_price"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 25),),
),*/
],
),
),
),
);
},
),
),
);
The
You are not using widget.category in restaurantLISTVIEW page but in ItemList widget, that's why you are getting that error.
Adjust your ItemList widget like this
class ItemList extends StatelessWidget {
final List list;
final String category;
ItemList({this.list, this.category});
}
So, your navigation line in ItemList must be
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context)=> new SarapanPagi(list: list, index: i, category: category)));
Also, in SarapanPagi page the variable type of category is not int by String
You are not using widget.category in restaurantLISTVIEW page but in ItemList widget,
The solution that I made is:
this code on the stateful widget class for the second page, needs to be improved by adding the value of the category.
ItemList(list: snapshot.data,)
improved code:
this code forwards the value store in the widget category to the second page from the stateful widget into stateless widget.
ItemList(list: snapshot.data,category: widget.category) :

check firestore has document or not using Future Builder

Full code
class yourBookings extends StatefulWidget {
#override
_yourBookingsState createState() => _yourBookingsState();
}
class _yourBookingsState extends State<yourBookings> {
StateModel appState;
bool _loadingVisible = false;
#override
Widget build(BuildContext context) {
appState = StateWidget.of(context).state;
final number = appState?.user?.number ?? '';
Future getPosts() async {
var firestore = Firestore.instance;
QuerySnapshot qn = await firestore
.collection("confirmed_c_rides2")
.document(number)
.collection("1")
.getDocuments();
return qn.documents;
}
return Scaffold(
appBar: AppBar(
title: Text("Your Bookings :"),
),
body: Container(
child: FutureBuilder(
future: getPosts(),
builder: (_, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Text("Loading ..."),
);
} else if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_, index) {
Widget image_carousel = new Container(
height: 200.0,
child: new Carousel(
//borderRadius: BorderRadius.all(Radius.circular(2.0)),
boxFit: BoxFit.fitHeight,
images: [
Image.network(
"${snapshot.data[index].data["driverImage"]}"),
Image.network(
"${snapshot.data[index].data["carImage"]}")
],
autoplay: true,
animationCurve: Curves.fastOutSlowIn,
animationDuration: Duration(milliseconds: 1000),
dotSize: 4.0,
indicatorBgPadding: 6.0,
dotBgColor: Colors.transparent,
),
);
return Card(
child: ListTile(
title: Column(
children: <Widget>[
SizedBox(height: 10),
Text(
"Status: ${snapshot.data[index].data["status"]}",
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
image_carousel,
Text(
"Name: ${snapshot.data[index].data["driverName"]}"),
SizedBox(height: 10),
Text(
"Gender: ${snapshot.data[index].data["gender"]}"),
SizedBox(height: 10),
Text(
"Experience: ${snapshot.data[index].data["experience"]}"),
SizedBox(height: 10),
Text(
"Number: ${snapshot.data[index].data["driverNumber"]}"),
SizedBox(height: 10),
Text(
"Time: ${snapshot.data[index].data["time"]}"),
SizedBox(height: 10),
Text(
"Scheduled on: ${snapshot.data[index].data["rideOn"]}"),
SizedBox(height: 10),
RaisedButton(
color: Colors.black,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => new issue()));
},
child: Text(
"Having issue",
style: TextStyle(color: Colors.white),
),
),
SizedBox(height: 10),
RaisedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => rating1()));
},
child: Text("Rate driver"),
)
],
),
),
);
});
} else if (snapshot==null) {
return Center(
child: Text("not found..."),
);
}
return Center(
child: Text("not found 2..."),
);
}),
),
);
}
}
getPosts() refers to the firestore location for fetching data.
I want to check whether firestore contains number or not as a document using Future Builder.How can i do that?
number -> 1 contains further details.
If number does not exists then show data from firestore else show "not found...".How can i do that?
Future builder is used to stream firestore.