Closure call with mismatched arguments using DateTime - flutter

I'm a designer dipping my toes on programming by following a tutorial. It's supposed to be an app that saves and shows transactions made within the last week. But I'm getting this error message whenever I try to add a transaction on the app. It throws me this error:
════════ Exception caught by gesture ═══════════════════════════════════════════
Closure call with mismatched arguments: function '_MyHomePageState._addNewTransaction'
Receiver: Closure: (String, double) => void from Function '_addNewTransaction#17043806':.
Tried calling: _MyHomePageState._addNewTransaction("Wednesday", 555.0, Instance of 'DateTime')
Found: _MyHomePageState._addNewTransaction(String, double) => void
════════════════════════════════════════════════════════════════════════════════
In simple terms, how could I fix this?
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class NewTransaction extends StatefulWidget {
final Function addTx;
NewTransaction(this.addTx);
#override
State<NewTransaction> createState() => _NewTransactionState();
}
class _NewTransactionState extends State<NewTransaction> {
final _titleController = TextEditingController();
final _amountController = TextEditingController();
DateTime _selectedDate;
void _submitData() {
if (_amountController.text.isEmpty) {
return;
}
final enteredTitle = _titleController.text;
final enteredAmount = double.parse(_amountController.text);
if (enteredTitle.isEmpty || enteredAmount <= 0 || _selectedDate == null) {
return;
}
widget.addTx(
enteredTitle,
enteredAmount,
_selectedDate,
);
Navigator.of(context).pop();
}
void _presentDatePicker() {
showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2023),
lastDate: DateTime.now(),
).then((pickedDate) {
if (pickedDate == null) {
return;
}
setState(() {
_selectedDate = pickedDate;
});
});
}
#override
Widget build(BuildContext context) {
return Card(
child: Container(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextField(
decoration: InputDecoration(labelText: 'Title'),
controller: _titleController,
onSubmitted: (_) => _submitData(),
),
TextField(
decoration: InputDecoration(labelText: 'Amount'),
controller: _amountController,
keyboardType: TextInputType.number,
onSubmitted: (_) => _submitData(),
),
Row(
children: [
Flexible(
fit: FlexFit.tight,
child: Text(
_selectedDate == null
? 'No Date Chosen'
: 'Picked Date: ${DateFormat.MEd().format(_selectedDate)}',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
TextButton(
child: Text(
'Choose Date',
style: TextStyle(fontWeight: FontWeight.bold),
),
onPressed: _presentDatePicker)
],
),
SizedBox(
height: 60,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.secondary,
foregroundColor:
Theme.of(context).textTheme.labelLarge.color,
textStyle: TextStyle(fontWeight: FontWeight.w600)),
onPressed: _submitData,
child: Text('Add transaction'),
),
)
],
),
),
);
}
}
What I've tried and sort of "worked"
It seems to run when I delete _selectedDate from the widget.addTx but without it, it won't save the transaction with the correct date.
What is supposed to happen
The problem occurs when I tap the Add Transaction button, it's supposed to save the transaction and show it on a list. But I can't seem to actually add a transaction since I've implemented the selectedDate parameter.

The error is due to a mismatch between how the addTx function is called and how the function passed in is actually defined. The number and/or types of arguments do not match.
Since you have not provided an example of how NewTransaction() is used, the best way to get to the bottom is to declare addTx more precisely.
Instead of
final Function addTx;
Declare it as
final void Function(String, double, DateTime) addTx;
Then you should see a static type-checking error at any location that passes in the incorrect function type.
See also PREFER signatures in function type annotations.

Related

Unable to perform NULL CHECK on DateTime type variable in IF condition and also while performing TERNARY operation

I have watched multiple videos for the solution but could not find the solution . I have declared a variable of DateTime type named _selectedDate. Firstly the complier is asking me to initialize the variable. With what value show I initialize it ? Also , I am performing a NULL check like this:
if(_selectedData == null )
As soon as I code this , there is an error which says The operand cannot be null,so the condition is always false , try removing the condition . Also , when I am performing a NULL check while using ternary operator , the complier is throwing the same error. I have also tried making this DateTime variable as nullable using question mark sign (?) but it doesn't work.
I am using a Date Picker in my app. It opens on a button click named CHOOSE DATE. I am expecting that whatever date I chose from the calendar , should be shown in the area where by default it is written "No Date Chosen ! . Code is given below:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class NewTransaction extends StatefulWidget {
final Function addTx;
const NewTransaction(this.addTx, {super.key});
#override
State<NewTransaction> createState() => _NewTransactionState();
}
class _NewTransactionState extends State<NewTransaction> {
final _titleController = TextEditingController();
final _amountController = TextEditingController();
DateTime _selectedDate = DateTime.now();
void _submitData() {
if (_amountController.text.isEmpty) {
return;
}
final enteredTitle = _titleController.text;
final enteredOutput = double.parse(_amountController.text);
widget.addTx(enteredTitle, enteredOutput);
// In the below statement I am not able to perform Null check on _selectedDate (_selectedDate == null).
if (enteredTitle.isEmpty || enteredOutput <= 0 || _selectedDate == null) {
return;
}
widget.addTx(enteredTitle, enteredOutput);
Navigator.of(context).pop();
}
void _presentDatePicker() {
showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2019),
lastDate: DateTime.now())
.then((pickedDate) {
if (pickedDate == null) {
return;
}
setState(() {
pickedDate = _selectedDate;
});
});
}
#override
Widget build(BuildContext context) {
return Card(
child: Container(
padding: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextField(
decoration: const InputDecoration(labelText: 'Title'),
controller: _titleController,
onSubmitted: (_) => _submitData(),
),
TextField(
decoration: const InputDecoration(labelText: 'Amount'),
controller: _amountController,
keyboardType: TextInputType.number,
onSubmitted: (_) => _submitData(),
),
// ignore: sized_box_for_whitespace
Container(
height: 70,
child: Row(
children: [
Text(_selectedDate == null // Here also I am facing the same issue
? 'No Date Chosen !'
: DateFormat.yMd().format(_selectedDate)),
const SizedBox(width: 25.0),
TextButton(
onPressed: _presentDatePicker,
child: const Text('Choose Date'),
),
],
),
),
ElevatedButton(
onPressed: _submitData,
child: const Text("Add Transaction"),
)
],
),
));
}
}
You initialize your _selectedDate variable with DateTime.now(); so it's absolutely normal that the compiler warn you about it can't be null.
You can remove the DateTime.now(); to fix your issue and also switch the set State like this : _selectedDate = pickedDate;
Then on your showDatePicker result, call the setState method with pickedDate even if it is null like this :
showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2019),
lastDate: DateTime.now())
.then((pickedDate) {
// if (pickedDate == null) {
// return;
// }
setState(() {
_selectedDate = pickedDate!;
});
});

Main page data is resetting automatically Flutter after user come back to second page to first page

I'm stuck with one issue where once I click on the upload image button it will take me to the next page wherein upload image class I will choose the images from the camera or Gallery and I will click on done. In the done button I have written navigation. pop(context) to the first page but when I come back all the text field data is cleared whatever I have entered and again I need to enter it back which is quite frustrating all the time...PLease help me to solve the issue or show the way how to save the data?
import '../blocs/addtrip_bloc.dart';
import '../widgets/customtextformfield.dart';
import 'CameraWidgetState.dart';
class DataInfoPage extends StatefulWidget {
const DataInfoPage({Key? key}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<DataInfoPage> {
_DataInfoPageState createState() => _DataInfoPageState();
String date = "";
final FirebaseAuth _auth = FirebaseAuth.instance;
User? user;
var name = '';
#override
void initState() {
super.initState();
initUser();
savedata();
}
initUser() async {
user = (await _auth.currentUser!);
name = user!.displayName!;
setState(() {});
}
void savedata() {
final absavedata = context.read<AddTripBloc>();
}
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
DateTime selectedDate = DateTime.now();
TextEditingController tripname = new TextEditingController();
TextEditingController sdate = new TextEditingController();
DateTimeRange? _selectedDateRange;
String _displayText(String begin, DateTime? date) {
if (date != null) {
return '$begin Date: ${date.toString().split(' ')[0]}';
} else {
return 'Press the button to show the picker';
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
SizedBox(
height: 20,
),
Text(
"Please enter trip details ",
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
color: Colors.black),
),
SizedBox(
height: 20,
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
customfields(
hintValue: ' Enter Trip Name',
labeltxt: 'Trip Name *',
keyboardtype: TextInputType.text,
text: tripname),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
FloatingActionButton(
onPressed: _show,
child: const Icon(Icons.date_range),
shape: BeveledRectangleBorder(
borderRadius: BorderRadius.circular(5))),
Column(
children: [
Text(
_displayText(
'Start', _selectedDateRange?.start),
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Colors.black),
),
SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () async {
await Navigator.of(context).push(MaterialPageRoute(
builder: (context) => CameraWidget()));
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => CameraWidget()));
},
child: const Text("Upload Images of Trip *"),
),
SizedBox(
height: 35,
),
],
)),
],
),
),
));
}
void _show() async {
final DateTimeRange? result = await showDateRangePicker(
context: context,
firstDate: DateTime(2022, 1, 1),
lastDate: DateTime(2030, 12, 31),
currentDate: DateTime.now(),
saveText: 'Done.',
);
if (result != null) {
// Rebuild the UI
print(result.start.toString());
setState(() {
_selectedDateRange = result;
});
}
}
}
Custom Flied Code
class customfields extends StatelessWidget {
customfields(
{required this.hintValue,
this.labeltxt = "",
required this.keyboardtype,
this.maxvalue = 1,
required this.text});
String hintValue;
String labeltxt;
int maxvalue;
TextInputType keyboardtype;
TextEditingController text;
bool _validate = false;
#override
Widget build(BuildContext context) {
return Center(
child: Column(
children: <Widget>[
TextFormField(
controller: text,
cursorColor: Colors.black,
//textAlign: TextAlign.left,
// autocorrect: true,
// textInputAction: TextInputAction.go,
// maxLines: maxvalue,
// autofocus: true,
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
textAlignVertical: TextAlignVertical.center,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(
RegExp('[a-z A-Z 0-9 #?!#%^&* ? # ^_ . : ! | "" \'-]')),
],
decoration: InputDecoration(
border: new UnderlineInputBorder(
// borderRadius: new BorderRadius.circular(5.0),
// borderSide: new BorderSide(),
),
hintText: hintValue,
labelText: labeltxt,
errorText: _validate ? 'Value Can\'t Be Empty' : null,
//prefixIcon: Icon(Icons),
//suffixIcon: Icon(Icons.currency_bitcoin)
),
keyboardType: keyboardtype,
validator: (value) {
if (value!.isEmpty) {
return "Value Can't be empty.";
}
return null;
},
),
],
),
);
}
}

Page refreshes when textformfield is focused on

In a 'Edit Profile' page, when a Textformfield is focused on to edit the text, the entire page reloads and doesn't allow me to change or input anything. The code is like this :
body: Form(
key: _formKey,
child: FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(
future: FirebaseFirestore.instance
.collection('appusers')
.doc(widget.id)
.get(),
builder: (_, snapshot) {
if (snapshot.hasError) {
print('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
var data = snapshot.data!.data();
var name = data!['name'];
return Padding(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 30),
child: Column(
children: [
Container(
margin: EdgeInsets.symmetric(vertical: 10),
child: TextFormField(
initialValue: name,
autofocus: false,
onChanged: (value) => name = value,
decoration: InputDecoration(
labelText: 'Name: ',
border: OutlineInputBorder(),
errorStyle:
TextStyle(color: Colors.redAccent, fontSize: 12),
),
validator: (value) {
RegExp regex = new RegExp(r'^.{3,}$');
if (value == null || value.isEmpty) {
return 'Please enter full name.';
}
if (!regex.hasMatch(value)) {
return ("Please enter a name.");
}
return null;
},
),
),
SizedBox(height: 40),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
updateUser(widget.id, name);
}
Navigator.of(context).pop();
},
child: Text(
'Update',
style: TextStyle(fontSize: 15),
),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
'Cancel',
style: TextStyle(fontSize: 15),
),
),
],
),
)
],
),
);
},
)),
Is there a reason why the page keeps being refreshed? There are other textfields similar to 'name' and clicking on any of those causes this page to reload. The formkey has been declared before Widget build as final _formKey = GlobalKey<FormState>();.
To give you an understanding of how flutter handles the app when the keyboard is opened.
When the keyboard is opened, flutter actually changes the screen size (i.e the bottom padding changes) because of this when you access the MediaQuery.of(context) in this widget it will cause the widget to rebuild so that MediaQuery.of(context) will return the updated MediaQueryData. This rebuilding is fine.
The problem is in the way you are using the FutureBuilder s future parameter. The FirebaseFirestore.instance.collection('appusers').doc(widget.id).get() will get executed everytime there is a rebuild of this EditProfile widget , but you probably want this to be called only once when the widget is loaded first time. So you need to initialize the future in the StatefulWidget initState like:
Future future;
#override
void initState() {
super.initState();
future = FirebaseFirestore.instance.collection('appusers').doc(widget.id).get();
}
Now this will not call the FirebaseFirestore call whenever the widget rebuilds. But there is another issue with your TextFormFields initialValue parameter. It uses the name variable which is declared and being initialized within the build method which does not seem right. You could do something like:
var name:
Future future;
#override
void initState() {
super.initState();
future = FirebaseFirestore.instance.collection('appusers').doc(widget.id).get();
future.then((value) {
if(value != null) {
var name = value.data!['name'];
}
});
}

Non-nullable instance field '_selectedDate' must be initialized

I am developing an Expenses Management App in flutter, Here I am trying to create a DateTimePicker using showDatePicker(). therefore Inside my presentDateTimePicker() function i am calling showDatePicker() method.
and I am creating a variable for selectedDate where I am not initializing it to a current value since it will change based on the user input.
Inside my setState() method I use _selectedDate = pickedDate.
Still, it shows an error saying "non-nullable instance field"
My widget
//flutter imports
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:intl/intl.dart';
class NewTransaction extends StatefulWidget {
final Function addTx;
NewTransaction(this.addTx);
#override
_NewTransactionState createState() => _NewTransactionState();
}
class _NewTransactionState extends State<NewTransaction> {
final _titleController = TextEditingController();
final _amountController = TextEditingController();
final _brandNameControlller = TextEditingController();
DateTime _selectedDate;
void _submitData() {
final enteredTitle = _titleController.text;
final enteredAmount = double.parse(_amountController.text);
final enteredBrandName = _brandNameControlller.text;
if (enteredTitle.isEmpty || enteredAmount <= 0) {
return;
}
widget.addTx(
enteredTitle,
enteredAmount,
enteredBrandName,
);
Navigator.of(context).pop();
}
void _presentDateTimePicker() {
showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2019),
lastDate: DateTime.now(),
).then((pickedDate) {
if (pickedDate == null) {
return;
}
setState(() {
_selectedDate = pickedDate;
});
});
}
#override
Widget build(BuildContext context) {
return Card(
elevation: 5,
child: Container(
padding: EdgeInsets.all(10),
child: Column(
children: <Widget>[
TextField(
autocorrect: true,
decoration: InputDecoration(labelText: 'Title'),
controller: _titleController,
onSubmitted: (_) => _submitData,
//onChanged: (val) {
//titleInput = val;
//},
),
TextField(
autocorrect: true,
decoration: InputDecoration(labelText: 'Amount'),
controller: _amountController,
keyboardType: TextInputType.number,
onSubmitted: (_) => _submitData,
//onChanged: (val) => amountInput = val,
),
TextField(
autocorrect: true,
decoration: InputDecoration(labelText: 'Brand Name'),
controller: _brandNameControlller,
onSubmitted: (_) => _submitData,
//onChanged: (val) => brandInput = val,
),
Container(
height: 70,
child: Row(
children: <Widget>[
Text(_selectedDate == null
? 'No Date Chosen'
: 'Picked Date: ${DateFormat.yMd().format(_selectedDate)}'),
FlatButton(
onPressed: _presentDateTimePicker,
child: Text(
'Chose Date',
style: TextStyle(fontWeight: FontWeight.bold),
),
textColor: Theme.of(context).primaryColor,
),
],
),
),
RaisedButton(
onPressed: _submitData,
child: Text('Add Transaction'),
color: Theme.of(context).primaryColor,
textColor: Theme.of(context).textTheme.button!.color,
),
],
),
),
);
}
}
If the value is nullable just mark the variable as such DateTime? _selectedDate;
And whenever you would use it just check for null first:
Text(_selectedDate == null
? 'No Date Chosen'
: 'Picked Date: ${DateFormat.yMd().format(_selectedDate!)}'),
// Here you do know that the value can't be null so you assert to the compiler that
Check out the official docs on null safety they are extremely high quality and instructive.
There you can read about when to use nullable ? non nullable or late variables.
There is a work around in this situation
initialize the date with
DateTime _selectedDate = DateTime.parse('0000-00-00');
and later on in text widget
instead of
Text(_selectedDate == null
? 'No Date Chosen'
: 'Picked Date: ${DateFormat.yMd().format(_selectedDate!)}'),
use
Text(_selectedDate == DateTime.parse('0000-00-00')
? 'No Date Chosen'
: 'Picked Date: ${DateFormat.yMd().format(_selectedDate!)}'),
If you will change the value in the setState method, you can initialize the variable with
DateTime _selectedDate = DateTime.now();
and format it to the format you show the user, this would get rid of the error and if you are going to change it each time the user selects a date, seeing the current date as a starting value gives the user a starting point as a reference.
step1 : Put a question mark '?' after DateTime data type such as DateTime? _selectedDate;
Adding a question mark indicates to Dart that the variable can be null. I expect that initially the _selectedDate is not set, so Dart is giving an error warning due to null-safety. By putting a question mark in the type, you are saying you expect that the variable can be null (which is why it fixes the error).
step2 : whenever you would use it just check for null first by adding a null check (!)
After fixing errors your code is now :
//flutter imports
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:intl/intl.dart';
class NewTransaction extends StatefulWidget {
final Function addTx;
NewTransaction(this.addTx);
#override
_NewTransactionState createState() => _NewTransactionState();
}
class _NewTransactionState extends State<NewTransaction> {
final _titleController = TextEditingController();
final _amountController = TextEditingController();
final _brandNameControlller = TextEditingController();
DateTime? _selectedDate;
void _submitData() {
final enteredTitle = _titleController.text;
final enteredAmount = double.parse(_amountController.text);
final enteredBrandName = _brandNameControlller.text;
if (enteredTitle.isEmpty || enteredAmount <= 0) {
return;
}
widget.addTx(
enteredTitle,
enteredAmount,
enteredBrandName,
);
Navigator.of(context).pop();
}
void _presentDateTimePicker() {
showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2019),
lastDate: DateTime.now(),
).then((pickedDate) {
if (pickedDate == null) {
return;
}
setState(() {
_selectedDate = pickedDate;
});
});
}
#override
Widget build(BuildContext context) {
return Card(
elevation: 5,
child: Container(
padding: EdgeInsets.all(10),
child: Column(
children: <Widget>[
TextField(
autocorrect: true,
decoration: InputDecoration(labelText: 'Title'),
controller: _titleController,
onSubmitted: (_) => _submitData,
//onChanged: (val) {
//titleInput = val;
//},
),
TextField(
autocorrect: true,
decoration: InputDecoration(labelText: 'Amount'),
controller: _amountController,
keyboardType: TextInputType.number,
onSubmitted: (_) => _submitData,
//onChanged: (val) => amountInput = val,
),
TextField(
autocorrect: true,
decoration: InputDecoration(labelText: 'Brand Name'),
controller: _brandNameControlller,
onSubmitted: (_) => _submitData,
//onChanged: (val) => brandInput = val,
),
Container(
height: 70,
child: Row(
children: <Widget>[
Text(_selectedDate == null
? 'No Date Chosen'
: 'Picked Date: ${DateFormat.yMd().format(_selectedDate!)}'),
FlatButton(
onPressed: _presentDateTimePicker,
child: Text(
'Chose Date',
style: TextStyle(fontWeight: FontWeight.bold),
),
textColor: Theme.of(context).primaryColor,
),
],
),
),
RaisedButton(
onPressed: _submitData,
child: Text('Add Transaction'),
color: Theme.of(context).primaryColor,
textColor: Theme.of(context).textTheme.button!.color,
),
],
),
),
);
}
}

How to start something automatically in flutter

I have the following code that initially displays a blank page, but I'd like an rAlert dialog to display automatically. Once the user clicks 'Request' or 'Cancel', some text will be displayed on the screen.
But I can't get the code to run that displays the Alert. I had it working by showing a button and clicking the button, but i need the Alert to display automatically when the page is displayed. I tried putting it in the initState. I didn't get any errors, but it didn't work either.
Anyone know what I need to do? Thanks?
import 'package:flutter/material.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
import 'dart:async';
import 'package:rostermeon/cwidgets/general_widgets.dart';
import 'package:rostermeon/rmo_constants.dart';
class ForgotPassword extends StatefulWidget {
static const String id = 'forgot_password_screen';
#override
_ForgotPasswordState createState() => _ForgotPasswordState();
}
class _ForgotPasswordState extends State<ForgotPassword> {
StreamController<bool> _events;
#override
initState() {
super.initState();
_events = new StreamController<bool>();
doRequest(context: context);
}
Future<bool> doSaveRequest({String pReason}) async {
await Future.delayed(const Duration(seconds: 3), () {});
return false;
}
Future<bool> doRequest({context}) {
String _reason = '';
GlobalKey<FormState> _formKey = GlobalKey<FormState>();
TextEditingController reasonController = TextEditingController();
TextStyle _style = TextStyle(fontFamily: 'Montserrat', fontSize: 18.0, fontWeight: FontWeight.normal);
InputDecoration _textFormFieldDecoration({String hintText, double padding}) => InputDecoration(
//contentPadding: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 8.0),
contentPadding: EdgeInsets.all(padding),
isDense: true,
hintText: hintText,
hintStyle: TextStyle(color: kHintText),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5)),
),
);
return Alert(
context: context,
title: 'Request New Password',
content: StreamBuilder<bool>(
initialData: false,
stream: _events.stream,
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
print(" ${snapshot.data.toString()}");
return snapshot.data
? CircularProgressIndicator()
: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 20.0),
Text('Email', textAlign: TextAlign.left, style: _style),
SizedBox(height: 10.0),
TextFormField(
validator: (value) {
if (value.isEmpty) {
return "please enter email";
}
return null;
},
onSaved: (value) {
_reason = value;
},
decoration: _textFormFieldDecoration(
hintText: 'your email address',
padding: 8.0,
),
controller: reasonController,
),
SizedBox(height: 10.0),
],
),
);
}),
buttons: [
DialogButton(
child: Text('Request', style: TextStyle(color: Colors.white, fontSize: 20)),
color: kMainColor,
onPressed: () async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
print(_reason);
_events.add(true);
var saved = await doSaveRequest(pReason: _reason);
if (saved) {
Navigator.pop(context, false);
} else {
_events.add(false);
}
Navigator.of(context).pop();
// Navigator.pop(context, false);
}
},
),
DialogButton(
child: Text('Cancel', style: TextStyle(color: Colors.white, fontSize: 20)),
color: kMainColor,
onPressed: () {
Navigator.pop(context, false);
},
),
],
).show();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: rmoAppBar(subText: 'Request New Password', hideBackButton: false),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[],
),
),
);
}
}
Dialogs/Alerts need the buildContext in order to work, You can't have the buildContext before build() method is called, that's why you can't just call it in initstate() before the build is called.
To make it work use addPostFrameCallback to make sure it delays until widget is built:
void initState() {
super.initState();
WidgetsBinding.instance
.addPostFrameCallback((_) => yourMethod(context));
}
https://www.didierboelens.com/2019/04/addpostframecallback/