how can i place forloop so that i dont get error? - flutter

how can i use forloop to generate values of data variable please help i am a beginner
class Mentions extends StatefulWidget {
const Mentions({
Key? key,
this.width,
this.height,
required this.fullname,
required this.username,
required this.photourl,
}) : super(key: key);
final double? width;
final double? height;
final List<String> fullname;
final List<String> username;
final List<String> photourl;
#override
_MentionsState createState() => _MentionsState();
}
class _MentionsState extends State<Mentions> {
List<Map<String, dynamic>> data = [];
void data1(
for(int i = 0; i< widget.fullname.length; i++) {
data.add({"Full Name": widget.fullname[i], "username": widget.username[i], "photourl" :widget.photourl[i] });
}
)
);
#override
Widget build(BuildContext context) {
return Container();
}
}

you can place your method inside initState
class _MentionsState extends State<Mentions> {
List<Map<String, dynamic>> data = [];
void data1 (){
for(int i = 0; i< widget.fullname.length; i++) {
data.add({
"Full Name": widget.fullname[i],
"username": widget.username[i],
"photourl" :widget.photourl[i]
});
}
)
}
#override
void initState() {
super.initState();
data1();
}
#override
Widget build(BuildContext context) {
return Container();
}
}

try this:
class Mentions extends StatefulWidget {
Mentions({
required this.fullname,
required this.username,
required this.photourl,
this.width,
this.height,
Key? key,
}) : super(key: key) {
for (var i = 0; i < fullname.length; i++) {
users.add({
'Full Name': fullname[i],
'username': username[i],
'photourl': photourl[i]
});
}
}
final double? width;
final double? height;
final List<String> fullname;
final List<String> username;
final List<String> photourl;
late final List<Map<String, dynamic>> users;
#override
_MentionsState createState() => _MentionsState();
}
class _MentionsState extends State<Mentions> {...}
then you can just use widget.users in _MentionsState. but you can even not set all this lists in widget constructor, do mapping to users before, and set to widget constructor just one list with users. and do you really need stateful widget instead of stateless?

Related

How to access values from another dart file?

I am new to flutter .Here I stored a value to a variable doc_id ,I want to use this value in another file called comments.dart . So I did something like below but it gives null value in comment.dart .
await FirebaseFirestore.instance
.collection('blogs')
.add({
'title': titleController.text,
}).then((value) {
doc_id = value.id;
comment(postid: docid);
successAlert(context);
}).catchError((error) =>
errorAlert(context));
Comment.dart
class comment extends StatefulWidget {
final String? postid;
const comment({Key? key, this.postid}) : super(key: key);
_commentState createState() => _commentState();
}
class _commentState extends State<comment> {
#override
Widget build(BuildContext context) {
return
Text(widget.postid);
}
}
Just create a global variable and assign from there
String postid = "";
class comment extends StatefulWidget {
final String? postid;
const comment({Key? key, this.postid}) : super(key: key);
_commentState createState() => _commentState();
}
class _commentState extends State<comment> {
#override
Widget build(BuildContext context) {
return
Text(postid);
}
}
void setPostID(String s) { // get value
postid = s;
}
Finally assign the value
await FirebaseFirestore.instance
.collection('blogs')
.add({
'title': titleController.text,
}).then((value) {
doc_id = value.id;
setPostID(value.id); // set value
comment(postid: docid);
successAlert(context);
}).catchError((error) =>
errorAlert(context));
You can use: https://pub.dev/packages/shared_preferences
await FirebaseFirestore.instance
.collection('blogs')
.add({
'title': titleController.text,
}).then((value) {
doc_id = value.id;
await prefs.setString('doc_id', postid); // set value
comment(postid: docid);
successAlert(context);
}).catchError((error) =>
errorAlert(context));
Finally use it in your class
class comment extends StatefulWidget {
final String? postid;
const comment({Key? key, this.postid}) : super(key: key);
_commentState createState() => _commentState();
}
class _commentState extends State<comment> {
#override
void initState() {
super.initState();
widget.postid = prefs.getString('doc_id'); // get the value
setState(() {});
}
#override
Widget build(BuildContext context) {
return
Text(postid);
}
}

how to use a data transfer from the parent widget?

Here is the child class that receives from its parent the index data that identifies the box to modify
class InformationPatient extends StatefulWidget {
final Patients patients;
final int index;
const InformationPatient(this.patients, this.index, {Key? key})
: super(key: key);
#override
State<InformationPatient> createState() => _InformationPatientState();
}
class _InformationPatientState extends State<InformationPatient> {
final int indexitem = 0;
late Box<Patients> boxPatient;
#override
void initState() {
super.initState();
boxPatient = Hive.box('Patient');
}
void _addNote(String newtitle, String newnote, String newconclusion) {
final newNOTE = Patients(
listOfNotes: [
ListNote(title: newtitle, note: newnote, conclusion: newconclusion)
],
);
boxPatient.put(indexitem, newNOTE);
Navigator.of(context).pop();
}
This way works but I don't have the index of the parent, I give it to him
final int indexitem = 0; <--- Works perfectly with my function patientbox.put() it receives the index
boxPatient.put(indexitem, newNOTE);
I would like to give indexbox the value of index but I don't know how to do it or if there is another way
final int indexitem = ??? <---- add the value of index
boxPatient.put(indexitem, newNOTE);
obviously I can't use index directly in the function boxPatient.put()
Thank you very much for your help
To read variables from the widget inside the state, you can simply refer to widget.<variable>. So in your example
boxPatient.put(widget.index, newNOTE);

How to use Hive to modify only one value of ca class model?

Here is my problem when I add a new patient to my boxPatient everything is added with the constructor of my class Patient.
After creating a patient I would like to be able to add notes to him so add to the box of this patient with boxpatient.put(index, value)
However, when I add a new value with the Patient constructor it modifies all the other fields with null which is normal but I was wondering if there was a way to avoid modifying all the other fields and to modify only the listnote field
Here is the addition to my patient box of a new patient:
class PatientList extends StatefulWidget {
const PatientList({Key? key}) : super(key: key);
#override
State<PatientList> createState() => _PatientListState();
}
class _PatientListState extends State<PatientList> {
List<Patients> patientList = [];
late Box<Patients> boxPatient;
#override
void initState() {
super.initState();
boxPatient = Hive.box('Patient');
//boxPatient.clear();
print('Patient ${boxPatient.values}');
}
void _bottomnewpatient(BuildContext ctx) {
TextEditingController namecontroller = TextEditingController();
TextEditingController firstnamecontroller = TextEditingController();
TextEditingController dateofbirthcontroller = TextEditingController();
TextEditingController emailcontroller = TextEditingController();
TextEditingController phonenumbercontroller = TextEditingController();
void _submitData() {
final enteredname = namecontroller.text;
final enteredfirstname = firstnamecontroller.text;
final entereddateofbirth = dateofbirthcontroller.text;
final enteredemail = emailcontroller.text;
final enteredphonenumber = phonenumbercontroller.text;
if (enteredname.isEmpty ||
enteredfirstname.isEmpty ||
entereddateofbirth.isEmpty ||
enteredemail.isEmpty ||
enteredphonenumber.isEmpty) {
print('No input');
return;
}
final newPT = Patients(
name: enteredname,
firstname: enteredfirstname,
dateofbirth: entereddateofbirth,
email: enteredemail,
numero: enteredphonenumber,
date: DateTime.now(),
id: DateTime.now().millisecondsSinceEpoch,
//id: DateTime.now().millisecondsSinceEpoch,
//listOfNotes: [],
);
boxPatient.add(newPT);
Navigator.of(context).pop();
}
And here is the addition of a new note to the patient box pointed by the index:
The problem here is that I call my constructor Patients() so it rebuilds all my fields how to avoid that.
With this builder also don't have the possibility to add more notes as it rebuilds each time.
class InformationPatient extends StatefulWidget {
final Patients patients;
final int index;
const InformationPatient(this.patients, this.index, {Key? key})
: super(key: key);
#override
State<InformationPatient> createState() => _InformationPatientState();
}
class _InformationPatientState extends State<InformationPatient> {
late Box<Patients> boxPatient;
#override
void initState() {
super.initState();
boxPatient = Hive.box('Patient');
}
void _addNote(String newtitle, String newnote, String newconclusion) {
final newNOTE = Patients(
listOfNotes: [
ListNote(title: newtitle, note: newnote, conclusion: newconclusion)
],
);
boxPatient.put(widget.index, newNOTE);
Navigator.of(context).pop();
}
and here is the class model:
import 'package:hive_flutter/hive_flutter.dart';
part 'listpatient.g.dart';
#HiveType(typeId: 0)
class Patients {
#HiveField(0)
final String? name;
#HiveField(1)
final String? firstname;
#HiveField(3)
final String? dateofbirth;
#HiveField(4)
final String? email;
#HiveField(5)
final String? numero;
#HiveField(6)
final DateTime? date;
#HiveField(7)
final int? id;
#HiveField(8)
final List<ListNote>? listOfNotes;
const Patients({
this.name,
this.firstname,
this.dateofbirth,
this.email,
this.numero,
this.date,
this.id,
this.listOfNotes,
});
}
#HiveType(typeId: 10)
class ListNote {
#HiveField(1)
final String? title;
#HiveField(2)
final String? note;
#HiveField(3)
final String? conclusion;
ListNote({
this.title,
this.note,
this.conclusion,
});
}
Thank you very much for your help! :)

How to display the middle element of a list in Flutter?

I have a similar widget for CupertinoPicker, but it was made by hand. I need to make the middle element of the list be selected by default, not the initial one as it is now. I've tried different options but haven't been able to do it yet. Please tell me how to implement this, I will be grateful for the help?
widget
class WheelSpeedPicker extends StatefulWidget {
final Function(dynamic) onValueChanged;
final int? startPosition;
final double itemSize;
final double? listHeight;
final int currentPosition;
final double? listWidth;
final FixedExtentScrollController? controller;
const WheelSpeedPicker({
Key? key,
required this.onValueChanged,
required this.currentPosition,
required this.itemSize,
this.startPosition,
this.listHeight,
this.controller,
this.listWidth,
}) : super(key: key);
#override
_WheelTimePickerState createState() {
return _WheelTimePickerState();
}
}
class _WheelTimePickerState extends State<WheelSpeedPicker> {
FixedExtentScrollController? fixedExtentScrollController;
int? currentPosition;
#override
void initState() {
super.initState();
currentPosition = widget.currentPosition;
fixedExtentScrollController = widget.controller ??
FixedExtentScrollController(initialItem: currentPosition ?? 0);
}
void _listener(int position) {
setState(() {
currentPosition = position;
});
widget.onValueChanged(currentPosition);
}
#override
void initState() {
super.initState();
// swap this
// currentPosition = widget.currentPosition;
// with this
currentPosition = (time.length / 2).floor();
fixedExtentScrollController = widget.controller ??
FixedExtentScrollController(initialItem: currentPosition ?? 0);
}
Other than that, I think your widget would be more useful if you added the items list to the widget parameters:
class WheelSpeedPicker extends StatefulWidget {
final Function(dynamic) onValueChanged;
final List<String> items;
final int? startPosition;
final double itemSize;
final double? listHeight;
final int currentPosition;
final double? listWidth;
final FixedExtentScrollController? controller;
const WheelSpeedPicker({
Key? key,
required this.items,
required this.onValueChanged,
required this.currentPosition,
required this.itemSize,
this.startPosition,
this.listHeight,
this.controller,
this.listWidth,
}) : super(key: key);
And then you'd have a more coherent set of parameters, because you already have a startPosition in the interface.
#override
void initState() {
super.initState();
currentPosition = widget.startPosition;
fixedExtentScrollController = widget.controller ??
FixedExtentScrollController(initialItem: startPosition ?? 0);
}

Dart/Flutter widget with optional parameters but at least one required

I'm trying to create a Flutter widget that can be initialized by various parameters, something like this
class MyWidget extends StatefulWidget {
final int? id;
final String? username;
MyWidget({this.id, this.username});
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
#override
void initState() {
super.initState();
if (widget.id != null) {
// init based on id
} else if (widget.username != null) {
// init based on username
} else {
// this should never happen
}
}
#override
Widget build(BuildContext context) {
return Container(); // build some widget
}
}
As you can see, neither of id and username are required, but I would need that at least one of them present. What would be a good way to approach this?
You can declare the constructor as anyone of these
MyWidget(this.id,{this.username});//ID is required. Usage will be MyWidget(1,usename:'test');
MyWidget(this.username,{this.id});//username is required Usage will be MyWidget('test',id:1);
MyWidget({required this.id, this.username}); //id required
MyWidget({this.id, required this.username});//username required
MyWidget({requried this.id, required this.username});//both required
And you can also use Assert Statement to check values at runtime have a look
MyWidget({this.id, this.username}):assert(id != null && username != null,'Both parameters cannot be null');
class TestWidget extends StatelessWidget {
final String id;
final String name;
const TestWidget.name({this.id, #required this.name});
const TestWidget.id({#required this.id, this.name});
#override
Widget build(BuildContext context) {
return Container(
child: Text(id ?? name),
);
}
}