The method was called on null Flutter error - flutter

I have seen many people having this error in other StackOverflow posts but when I am struggling to implement the answers to other questions to my own code. The code being used is from the GitHub repository https://github.com/sbis04/events_demo.
This is how I call the method:
class _ThirdRoute extends State<ThirdRoute> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Calendar"),
),
body: Column(
children: <Widget>[
DashboardScreen(),
],
),
);
}
}
And this is the method in another .dart file:
class DashboardScreen extends StatefulWidget {
#override
_DashboardScreenState createState() => _DashboardScreenState();
}
class _DashboardScreenState extends State<DashboardScreen> {
Storage storage = Storage();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.white,
iconTheme: IconThemeData(
color: Colors.grey, //change your color here
),
title: Text(
'Event Details',
style: TextStyle(
fontSize: 22,
),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => CreateScreen(),
),
);
},
),
body: Padding(
padding: const EdgeInsets.only(
left: 16.0,
right: 16.0,
),
child: Container(
child: StreamBuilder(
stream: storage.retrieveEvents(),
builder: (context, snapshot) {
if (snapshot.hasData) {
if (snapshot.data.documents.length > 0) {
return ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
Map<String, dynamic> eventInfo = snapshot.data.documents[index].data();
EventInfo event = EventInfo.fromMap(eventInfo);
DateTime startTime = DateTime.fromMillisecondsSinceEpoch(event.startTimeInEpoch);
DateTime endTime = DateTime.fromMillisecondsSinceEpoch(event.endTimeInEpoch);
String startTimeString = DateFormat.jm().format(startTime);
String endTimeString = DateFormat.jm().format(endTime);
String dateString = DateFormat.yMMMMd().format(startTime);
return Padding(
padding: EdgeInsets.only(bottom: 16.0),
child: InkWell(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => EditScreen(event: event),
),
);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: EdgeInsets.only(
bottom: 16.0,
top: 16.0,
left: 16.0,
right: 16.0,
),
= child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 10),
Text(
event.description,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
SizedBox(height: 10),
Padding(
padding: const EdgeInsets.only(top: 8.0, bottom: 8.0),
child: Text(
event.link,
),
),
SizedBox(height: 10),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 50,
width: 5,
),
SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
dateString,
),
Text(
'$startTimeString - $endTimeString',
),
],
)
],
),
],
),
),
],
),
),
);
},
);
} else {
return Center(
child: Text(
'No Events',
),
);
}
}
return Center(
child: CircularProgressIndicator(
strokeWidth: 2,
),
);
},
),
),
),
);
}
}
If anyone would be able to give me some advice on how to solve the error:
The method 'collection' was called on null. Receiver: null. Tried calling: collection("events"). The relevant error-causing widget was DashboardScreen
EDIT This is my storage.dart file as requested in the comments:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'calendar_client.dart';
final CollectionReference mainCollection = FirebaseFirestore.instance.collection('event');
final DocumentReference documentReference = mainCollection.doc('test');
class Storage {
Future<void> storeEventData(EventInfo eventInfo) async {
DocumentReference documentReferencer = documentReference.collection('events').doc(eventInfo.id);
Map<String, dynamic> data = eventInfo.toJson();
print('DATA:\n$data');
await documentReferencer.set(data).whenComplete(() {
print("Event added to the database, id: {${eventInfo.id}}");
}).catchError((e) => print(e));
}
Future<void> updateEventData(EventInfo eventInfo) async {
DocumentReference documentReferencer = documentReference.collection('events').doc(eventInfo.id);
Map<String, dynamic> data = eventInfo.toJson();
print('DATA:\n$data');
await documentReferencer.update(data).whenComplete(() {
print("Event updated in the database, id: {${eventInfo.id}}");
}).catchError((e) => print(e));
}
Future<void> deleteEvent({#required String id}) async {
DocumentReference documentReferencer = documentReference.collection('events').doc(id);
await documentReferencer.delete().catchError((e) => print(e));
print('Event deleted, id: $id');
}
Stream<QuerySnapshot> retrieveEvents() {
Stream<QuerySnapshot> myClasses = documentReference.collection('events').orderBy('start').snapshots();
return myClasses;
}
}

Related

List screen to product details scree

I'm confused in this. I have created a screen in with list to products data is coming from an dummy API. no I have created the cards and I want to display product details in next screen. how can I show the same product details on second screen of pressed product.
I think we need to store index of api data in a variable somehow. this is the code
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_get_api/model.dart';
import 'package:flutter_get_api/product_detail.dart';
import 'package:http/http.dart' as http;
class Details extends StatefulWidget {
Details({Key? key}) : super(key: key);
#override
State<Details> createState() => _DetailsState();
}
class _DetailsState extends State<Details> {
Future<Model> getProductsApi() async {
final responce =
await http.get(Uri.parse('https://dummyjson.com/products'));
var data = jsonDecode(responce.body.toString());
if (responce.statusCode == 200) {
return Model.fromJson(data);
} else {
return Model.fromJson(data);
}
}
var s = '\$';
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: Drawer(),
appBar: AppBar(
backgroundColor: Color.fromARGB(255, 32, 28, 80),
title: Text('Api Get'),
),
backgroundColor: Color.fromARGB(255, 32, 28, 80),
body: Column(
children: [
Expanded(
child: FutureBuilder<Model>(
future: getProductsApi(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.products!.length,
itemBuilder: (context, index) {
print(
snapshot.data!.products!.length,
);
return Column(
children: [
Padding(
padding: const EdgeInsets.all(5.0),
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProductDetails(),
));
},
child: Container(
height: 100,
width: 500,
child: Card(
color: Color.fromARGB(255, 185, 239, 243),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(
10, 25, 10, 10),
child: CircleAvatar(
backgroundImage: NetworkImage(snapshot
.data!.products![index].thumbnail!
.toString()),
),
),
Flexible(
child: Padding(
padding: const EdgeInsets.fromLTRB(
8, 10, 8, 0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Text(
snapshot
.data!.products![index].title
.toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 17),
),
Text(
snapshot
.data!.products![index].brand
.toString(),
style: TextStyle(
fontWeight: FontWeight.bold),
),
Text(
snapshot.data!.products![index]
.description
.toString(),
),
],
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('\$' +
snapshot.data!.products![index].price
.toString()),
),
],
),
),
),
),
Pass your selected product to the ProductDetails constructor
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProductDetails(snapshot.data!.products[index]),));
Watch the basics here: https://docs.flutter.dev/cookbook/navigation/passing-data
You can pass through constructor
class ProductDetails extends StatefulWidget {// can be StatelessWidget
final data; // better use DataType like `final ModeClass data
const ProductDetails({super.key, required this.data});
Now you can pass it like
builder: (context) => ProductDetails(snapshot.data!.products![index]),
Also you can pass with route arguments. Check more about navigation/passing-data

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.

How to Fix List Items are automatically changing their positing in flutter?

I am calling API data inside Listview. builder in flutter but the error I am facing is the items are changing their positions automatically.
For Example, When I load this class for the First Time the arrangement of List items is the same as required but after 30-40 seconds the List items arrangement automatically starts changing, and data showing itself randomly.
I am looking for someone who can help me to fix this issue?
For this purpose here is myClass Code.
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart'as HTTP;
import 'package:worldcup/utils/colors.dart';
class SeriesSchedulePage extends StatefulWidget {
#override
_SeriesSchedulePageState createState() => _SeriesSchedulePageState();
}
class _SeriesSchedulePageState extends State<SeriesSchedulePage> {
List<dynamic> matches = [];
var match;
getSchedule() async {
http.Response response = await http
.get(Uri.parse("https://api.cricket.com.au/matches/2780"));
final Map parseData = await json.decode(response.body.toString());
matches = parseData['matchList']["matches"];
setState(() {
match = matches;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.primaryWhite,
appBar: AppBar(
backgroundColor: AppColors.yellow,
elevation: 0,
centerTitle: true,
leading: IconButton(
onPressed: () {
Navigator.pop(context,true);
},
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
),
title: Text(
'Schedule',
textScaleFactor: 0.9,
style: GoogleFonts.openSans(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 17),
),
),
body: Container(
child: FutureBuilder(
future: getSchedule(),
builder: (context, snapshot) {
if (match == null) {
return Center(
child: CupertinoActivityIndicator(
animating: true, radius: 15));
} else
return ListView.builder(
itemCount: matches.length,
shrinkWrap: true,
reverse: false,
itemBuilder: (context, index) {
if (matches[index]["status"] =="UPCOMING") {
return Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(7),
),
child: Container(
width: double.infinity,
child: Padding(
padding: EdgeInsets.only(left: 15, top: 7, bottom: 7, right: 15),
child: Row(
children: [
SizedBox(width: 20,),
Expanded(
flex: 2,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
matches[index]['name'].toString(),
textScaleFactor: 0.9,
style: GoogleFonts.openSans(
fontWeight: FontWeight.w700, fontSize: 15),
),
SizedBox(height: 10,),
Text(
matches[index]["homeTeam"]['name'].toString(),
textScaleFactor: 0.9,
style: GoogleFonts.openSans(
fontWeight: FontWeight.w700, fontSize: 15),
),
SizedBox(height: 10,),
Text(
matches[index]["awayTeam"]['name'].toString(),
textScaleFactor: 0.9,
style: GoogleFonts.openSans(
fontWeight: FontWeight.w500, fontSize: 13),
),
],
),
],
),
),
],
),
),
)
);
} else {
return Center(
child: Text("No Upcoming Match in this series"),
);
}
}
);
},
),
)
);
}
}
The issue is because getSchedule() has a setState inside it. When the build method is called, getSchedule() will trigger, and since it is calling setState , the build method is being called again, causing your widgets to continuously rebuild in an infinite loop.
What you need to do is prevent such a loop from happening. I see that you are using FutureBuilder too, that is a solution but your implementation is incorrect.
What you should do is this:
Future<List<dynamic>> getSchedule() async {
http.Response response =
await http.get(Uri.parse("https://api.cricket.com.au/matches/2780"));
final Map parseData = await json.decode(response.body.toString());
var matches = parseData['matchList']["matches"];
return matches;
}
This function returns a Future<List<dynamic>> which your future builder can use to handle the builds. For info on future builder here https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html.
Since you FutureBuilder will react to what is provided by getSchedule() when the future is complete, you do not need to use setState to rebuild.
I have modified your SeriesShedualPage here is the full code:
class SeriesSchedulePage extends StatefulWidget {
#override
_SeriesSchedulePageState createState() => _SeriesSchedulePageState();
}
class _SeriesSchedulePageState extends State<SeriesSchedulePage> {
Future<List<dynamic>> getSchedule() async {
http.Response response =
await http.get(Uri.parse("https://api.cricket.com.au/matches/2780"));
final Map parseData = await json.decode(response.body.toString());
var matches = parseData['matchList']["matches"];
return matches;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: FutureBuilder<List<dynamic>>(
future: getSchedule(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<dynamic> matches = snapshot.data!;
return ListView.builder(
itemCount: matches.length,
shrinkWrap: true,
reverse: false,
itemBuilder: (context, index) {
if (matches[index]["status"] == "UPCOMING") {
return Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(7),
),
child: Container(
width: double.infinity,
child: Padding(
padding: EdgeInsets.only(
left: 15, top: 7, bottom: 7, right: 15),
child: Row(
children: [
SizedBox(
width: 20,
),
Expanded(
flex: 2,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
matches[index]['name'].toString(),
textScaleFactor: 0.9,
),
SizedBox(
height: 10,
),
Text(
matches[index]["homeTeam"]['name']
.toString(),
textScaleFactor: 0.9,
),
SizedBox(
height: 10,
),
Text(
matches[index]["awayTeam"]['name']
.toString(),
textScaleFactor: 0.9,
),
],
),
],
),
),
],
),
),
));
} else {
return Center(
child: Text("No Upcoming Match in this series"),
);
}
});
}
return Center(
child: CupertinoActivityIndicator(animating: true, radius: 15));
},
),
));
}
}

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

Flutter always needing a hot reload

I'm making an app. I'm getting data from the URL and try to show. But I need to hot reload to see.
These are my codes:
import 'package:flutter/material.dart';
import 'widgets/half_category_widget.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
var searchCat;
var baslik="Ana Sayfa";
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData.light(),
home: FirstApp(),
));
createCategory();
createProduct();
}
void runCat(id){
searchCat=id+1;
searchProds();
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData.light(),
home: CatProds(),
));
}
class FirstApp extends StatefulWidget {
#override
_FirstAppState createState() => _FirstAppState();
}
List<Widget> menu = new List<Widget>();
Future createCategory() async{
var url = 'https://recepabi.com/pc/getCatKafe';
http.Response response = await http.get(url);
var data = (response.body).toString().split('-');
for(var i=0;i<data.length-1;i++){
menu.add(Expanded(
child: Padding(
padding: const EdgeInsets.all(4.0),
child:
InkWell(onTap: () {
print("ID:" + i.toString());
runCat(i);
baslik=data[i];
},
child: Container(
height: 100.0,
width: 100.0,
child: Column(
children: <Widget>[
HalfCategory(Colors.blue, Icons.menu, data[i]),
],
),
),
) ,
),
));
}
}
List<Widget> products = new List<Widget>();
List<Widget> products1 = new List<Widget>();
Future createProduct() async{
var url = 'https://recepabi.com/pc/getProdKafe';
http.Response response = await http.get(url);
var data = (response.body).toString().split('ğ');
for(var i=0;i<data.length-1;i++){
var prod=data[i].split("ı");
var ad=prod[0];
var birim=prod[1];
var kategori=prod[2];
var fiyat=prod[3];
var resim=prod[4];
var myr=Row(children: <Widget>[Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 5.0, right: 5.0 ),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: Image.network(
resim,
fit: BoxFit.cover,
repeat: ImageRepeat.noRepeat,
height: 200.0,
),
),
),
Padding(
padding: const EdgeInsets.only(top: 16.0,bottom: 16.0),
child: Text(
ad.toUpperCase(),
maxLines: 1,
style: TextStyle(fontSize: 25.0),
textAlign: TextAlign.center,
),
)
],
),
),
),],);
products1.add(myr);
}
}
class _FirstAppState extends State<FirstApp> {
int _index = 0;
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Kafeex"),
centerTitle: true,
backgroundColor: Colors.red,
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _index,
onTap: (int index) {
setState(() {
_index = index;
if(_index==0)
{
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => FirstApp()),
(Route<dynamic> route) => false,
);
}
else if(_index==1)
{
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
(Route<dynamic> route) => false,
);
}
});
},
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.fastfood),
title: new Text('Sipariş'),
),
BottomNavigationBarItem(
icon: new Icon(Icons.shopping_cart),
title: new Text('Sepet'),
),
],
),
body: Padding(
padding: const EdgeInsets.all(2.0),
child: ListView(
scrollDirection: Axis.vertical,
children: <Widget>[
Row(
children:menu
),
SizedBox(
height: 8.0,
),
Padding(
padding: const EdgeInsets.all(6.0),
child: Row(
children: <Widget>[Expanded(
child: Text(baslik,
style: TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.start,
),
),],
),
),
SizedBox(
height: 10.0,
),
Column(
children: products1
),
],
),
)
);
}
}
class SecondRoute extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
class CatProds extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Kafeex"),
centerTitle: true,
backgroundColor: Colors.red,
),
body: Padding(
padding: const EdgeInsets.all(2.0),
child: ListView(
scrollDirection: Axis.vertical,
children: <Widget>[
Row(
children:menu
),
SizedBox(
height: 8.0,
),
Padding(
padding: const EdgeInsets.all(6.0),
child: Row(
children: <Widget>[Expanded(
child: Text(baslik,
style: TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.start,
),
),],
),
),
SizedBox(
height: 10.0,
),
Column(
children: searchProd
),
],
),
)
);
}
}
List<Widget> searchProd = new List<Widget>();
Future searchProds() async{
var url = 'https://recepabi.com/pc/searchProdKafe/'+searchCat.toString();
print(url);
http.Response response = await http.get(url);
var data = (response.body).toString().split('ğ');
for(var i=0;i<data.length-1;i++){
var prod=data[i].split("ı");
var ad=prod[0];
var birim=prod[1];
var kategori=prod[2];
var fiyat=prod[3];
var resim=prod[4];
var myr2=Row(children: <Widget>[Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 5.0, right: 5.0 ),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: Image.network(
resim,
fit: BoxFit.cover,
repeat: ImageRepeat.noRepeat,
height: 200.0,
),
),
),
Padding(
padding: const EdgeInsets.only(top: 16.0,bottom: 16.0),
child: Text(
ad.toUpperCase(),
maxLines: 1,
style: TextStyle(fontSize: 25.0),
textAlign: TextAlign.center,
),
)
],
),
),
),],);
searchProd.add(myr2);
searchCat=0;
}
}
For example: I get the data from URL(createCategory()). I put the data to list(menu) and try to show on the widget(_FirstAppState's widget). But first, run nothing appears. On the second run(by hot reloading) it appears.
How do I prevent this?
The problem here is u r calling createCategory(); & createProduct(); functions in main() function if u change some code in those methods u need to call main() method again which is not possible in hot reload which only changes state & some widget
so for calling main() method again u need to perform hot restart