I have two files. File 1 has a nameController and file2 has emailController and passwordController.
I want to access the nameController from file1 in file2 which has the .registerUsingEmailPassword() method .
file1
class UserName extends StatefulWidget {
const UserName({Key? key}) : super(key: key);
#override
State<UserName> createState() => _UserNameState();
}
final _registerFormKey = GlobalKey<FormState>();
final _nameTextController = TextEditingController();
...
Form(
key: _registerFormKey,
child: TextFormField(
controller: _nameTextController,
..
));
}
file2
class SignUp extends StatefulWidget {
const SignUp({Key? key}) : super(key: key);
#override
State<SignUp> createState() => _SignUpState();
}
class _MyEmailState extends State<SignUp> {
final _regFormKey = GlobalKey<FormState>();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
...
if (_regFormKey.currentState!.validate()) {
User? user = await FireAuth.registerUsingEmailPassword(
name: _nameTextController.text, // I want to access this controller from
file1
email: _emailTextController.text,
password:_passwordTextController.text,
);
}
}
Can somebody help please.
You must be going from file 1 to file 2 through navigator, pass the data from nameController as an argument to the Navigator like,
Navigator.of(context).pushNamed('file2Route', arguments:nameController.text);
Get the text in file2 as
var nameText = ModalRoute.of(context)!.settings.arguments as String;
Then simply use the nameText in registerUsingEmailPassword() method.
If this is not the case, please do specify.
Cheers!!
class SignUp extends StatefulWidget {
final TextEditingController nameController; // pass via constructor
const SignUp({Key? key,required TextEditingController nameController}) : super(key: key);
#override
State<SignUp> createState() => _SignUpState();
}
then use in build like this
if (_regFormKey.currentState!.validate()) {
User? user = await FireAuth.registerUsingEmailPassword(
name: widget.nameController.text, // use like this
email: _emailTextController.text,
password:_passwordTextController.text,
);
Related
I am sending 2 parameters restaurantDetails.rest_latitude and restaurantDetails.rest_longitude to a class to get the map details
BarMapWidget(restaurantDetails.rest_latitude, restaurantDetails.rest_longitude),
In the class I have a stateful widget
class BarMapWidget extends StatefulWidget {
String restLatitude;
String restLongitude;
BarMapWidget(this.restLatitude, this.restLongitude, {Key? key}) : super(key: key);
#override
_BarMapWidgetState createState() => _BarMapWidgetState();
}
I am passing a string so I know I have to make it a double
Here is the extended class,
class _BarMapWidgetState extends State<BarMapWidget> {
// Destination Longitude
final double _destLatitude = restLatitude;
final double _destLongitude = restLongitude;
void initState() {
// Add destination marker
_addMarker(
LatLng(_destLatitude, _destLongitude),
"destination",
// BitmapDescriptor.defaultMarkerWithHue(90),
BitmapDescriptor.defaultMarker
);
super.initState();
}
Which give me a Undefined name 'restLatitude'. and Undefined name 'restLongitude'.
How can I access the variable in BarMapWidget?
Your restLatitude and restLongitude on widget level, try using widget.variableName. Also, those aren't matching datatype.
If you need double convert BarMapWidget variable to double.
To initialize on state level you can trick with using late or use initState;
class BarMapWidget extends StatefulWidget {
final double restLatitude;
final double restLongitude;
const BarMapWidget(this.restLatitude, this.restLongitude, {Key? key})
: super(key: key);
#override
_BarMapWidgetState createState() => _BarMapWidgetState();
}
class _BarMapWidgetState extends State<BarMapWidget> {
// Destination Longitude
late final double _destLatitude = widget.restLatitude;
late final double _destLongitude = widget.restLongitude;
Just add in
widget.restLatitude
I'm following tutorial on udemy and i found this weird error and i already read some doccumentation and i still didnt find the right answer to have constructor with initail value.
her is my code
class MapScreen extends StatefulWidget {
final PlaceLocation initialLocation;
final bool isSelecting;
const MapScreen({Key? key, this.initialLocation = PlaceLocation( //here there is an error "The default value of an optional parameter must be constant. (Documentation)"
latittude: 37.422,
longitude: -122.084,
address: "Example stree no 1",
), this.isSelecting = false}) : super(key: key);
#override
_MapScreenState createState() => _MapScreenState();
}
however if i delete those const new error come out
class MapScreen extends StatefulWidget {
final PlaceLocation initialLocation;
final bool isSelecting;
MapScreen({Key? key, this.initialLocation = PlaceLocation( //The default value of an optional parameter must be constant. (Documentation)
latittude: 37.422,
longitude: -122.084,
address: "Jl. Imambonjol",
), this.isSelecting = false}) : super(key: key);
#override
_MapScreenState createState() => _MapScreenState();
}
i also tried to follow the instruction and modify my code like this:
class MapScreen extends StatefulWidget {
final PlaceLocation initialLocation;
final bool isSelecting;
MapScreen({
this.initialLocation =
const PlaceLocation(latitude: 37.422, longitude: -122.084),
this.isSelecting = false,
});
#override
_MapScreenState createState() => _MapScreenState();
}
but the error still came out
I was able to fix your mistake, below I will attach the solution code and a screenshot of the console:
// Fake model:
class PlaceLocation {
final double latittude;
final double longitude;
final String address;
// Make this constructor const to solve your problem:
const PlaceLocation(
{required this.latittude,
required this.longitude,
required this.address});
}
class MapScreen extends StatefulWidget {
final PlaceLocation initialLocation;
final bool isSelecting;
// Also don't forget to put const before PlaceLocation() in this constructor:
const MapScreen(
{Key? key,
this.initialLocation = const PlaceLocation(
latittude: 37.422,
longitude: -122.084,
address: "Example stree no 1",
),
this.isSelecting = false})
: super(key: key);
#override
_MapScreenState createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
#override
Widget build(BuildContext context) {
// Console test to check default values:
print("lattitude: " +
MapScreen().initialLocation.latittude.toString() +
"\nlongitude: " +
MapScreen().initialLocation.longitude.toString() +
"\naddress: " +
MapScreen().initialLocation.address.toString());
return Scaffold(body: Container());
}
}
All you have to do is make your model (PlaceLocation) constructor const.
class Notice extends StatefulWidget {
final String s_id;
const Notice({Key key, this.s_id}) : super(key: key);
#override
_NoticeState createState() => _NoticeState();
}
class _NoticeState extends State<Notice> {
TextEditingController _titleController = new TextEditingController();
var api =
Uri.parse('https://www.a2rstore.in/api/school/v1/noticeApi.php?id=${widget.s_id}');
You can't call the "widget" without the context.
The proper way to do it is by first defining your variable:
class _NoticeState extends State<Notice> {
TextEditingController _titleController = new TextEditingController();
var api;
...
}
And then assigning to it the value either in the build or initState method:
#override
initState(){
api = Uri.parse('https://www.a2rstore.in/api/school/v1/noticeApi.php?id=${widget.s_id}');
}
In my first page I have this:
onPressed: () {
Navigator.push(context,MaterialPageRoute(
builder: (context) =>
UpdateAttackScreen(
idAttack: idAttack,
title: title,
descriptionAttack:descriptionAttack,
indexSensations:indexSensations)));
},
in the second page where I want to receive this params:
class UpdateAttackScreen extends StatefulWidget {
final String idAttack;
final String title;
final String descriptionAttack;
final List<dynamic> indexSensations;
UpdateAttackScreen(
{Key key,
#required this.idAttack,
#required this.title,
#required this.descriptionAttack,
#required this.indexSensations})
: super(key: key);
#override
_UpdateAttackScreenState createState() => _UpdateAttackScreenState(idAttack, title, descriptionAttack, indexSensations);
}
class _UpdateAttackScreenState extends State<UpdateAttackScreen> {
String idAttack;
String title;
String descriptionAttack;
List<dynamic> indexSensations;
_UpdateAttackScreenState(idAttack, title, descriptionAttack, indexSensations);
TextEditingController _titleController = TextEditingController()..text = title;
TextEditingController _descriptionController = TextEditingController()..text = descriptionAttack;
The response error on title and descriptionAttack:
The instance member 'title' can't be accessed in an initializer.
Try replacing the reference to the instance member with a different expression
this code
TextEditingController _titleController = TextEditingController()..text = title;
TextEditingController _descriptionController = TextEditingController()..text = descriptionAttack;
replace with this
TextEditingController _titleController;
TextEditingController _descriptionController;
#override
void initState() {
super.initState();
_titleController = TextEditingController()..text = title;
_descriptionController = TextEditingController()..text = descriptionAttack;
}
Solution 1 :
Wrap _titleController with initState method
String title = '';
TextEditingController _titleController;
#override
void initState() {
_titleController..text = title;
super.initState();
}
Solution 2:
Transform the title variable into a static variable to be able to use it everywhere in your class
static String title = '';
TextEditingController _titleController = TextEditingController()..text = title ;
I fixed it!
class UpdateAttackScreen extends StatefulWidget {
final String idAttack;
final String title;
final String descriptionAttack;
final List<dynamic> indexSensations;
UpdateAttackScreen(
{Key key,
#required this.idAttack,
#required this.title,
#required this.descriptionAttack,
#required this.indexSensations})
: super(key: key);
#override
_UpdateAttackScreenState createState() => _UpdateAttackScreenState(idAttack, title, descriptionAttack, indexSensations);
}
class _UpdateAttackScreenState extends State<UpdateAttackScreen> {
String idAttack;
String title;
String descriptionAttack;
List<dynamic> indexSensations;
_UpdateAttackScreenState(idAttack, title, descriptionAttack, indexSensations);
TextEditingController _titleController;
TextEditingController _descriptionController;
Inside the TextFieldForm
initialValue: widget.title,
I got a Visual Studio warning on my class (below) saying "This class (or a class which this class inherits from) is marked as '#immutable', but one or more of its instance fields are not final: UserSignIn._email", but I cannot mark this argument as final because I initialise it in the constructor
Without final :
class UserSignIn extends StatefulWidget {
TextEditingController _email;
UserSignIn({String emailInput}) {
this._email = TextEditingController(text: (emailInput ?? ""));
}
#override
_UserSignInState createState() => _UserSignInState();
}
class _UserSignInState extends State<UserSignIn> {
#override
Widget build(BuildContext context) {
...
}
}
How to do this ?
Thank you
You should put the TextEditingController in the state class and initialise it in the initState method, like this.
And keep in mind that the StatefulWidget can be different every time when the widget tree is changed, so don't put anything in there that is not immutable.
Keep everything dynamic in the State class
class UserSignIn extends StatefulWidget {
final String emailInput;
const UserSignIn({Key key, this.emailInput}) : super(key: key);
#override
_UserSignInState createState() => _UserSignInState();
}
class _UserSignInState extends State<UserSignIn> {
TextEditingController _controller;
#override
void initState() {
_controller = TextEditingController(text: widget.emailInput);
super.initState();
}
...
}