Flutter - LateError (LateInitializationError: Field '_items@68190616' has not been initialized.)
Try on initState() create Empty map before using it. because when enter build phase it access to null map which throw error.
@override
void initState() {
_items = <Map<String,dynamic>>[] // Empty one
_items = _getData(); // Or you can assign it immediately
super.initState();
}
Edit: Try to separate the Initiate from the initState
, Because the error that you showed me is that must be Future as await
and cast it to the required Type (in this case is List<Map<String, dynamic>>
)
@override
void initState() {
_getDataInit();
super.initState();
}
void _getDataInit() async {
_items = await _getData() as List<Map<String, dynamic>>;
}
Edit2: After investigation, It turns out there wrong Future implementation. I've add FutureBuilder
and removed initState
and _items
variable to solve the issue and here's the working code (just paste it as form.dart):
import 'database.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:select_form_field/select_form_field.dart';
import 'package:date_time_picker/date_time_picker.dart';
class MyCustomForm extends StatefulWidget {
const MyCustomForm({Key? key}) : super(key: key);
@override
MyCustomFormState createState() {
return MyCustomFormState();
}
}
class MyCustomFormState extends State<MyCustomForm> {
final _formKey = GlobalKey<FormState>();
var nameController = TextEditingController();
var dateController = TextEditingController();
var courseController = TextEditingController();
var scoreController = TextEditingController();
final dateFormat = DateFormat('dd-MM-yyyy');
final database = Database();
@override
void dispose() {
nameController.dispose();
dateController.dispose();
courseController.dispose();
scoreController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
bool shouldDisplay = false;
return Form(
key: _formKey,
child: FutureBuilder<List<Map<String, dynamic>>>(
future: database.getBandits(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
if (snapshot.hasError) {
return ErrorWidget(Exception(
'Error occured when fetching data from database'));
} else if (!snapshot.hasData) {
return const Center(child: Text('Bandit is empty!'));
} else {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 30.0),
child: SelectFormField(
controller: nameController,
hintText: "...",
items: snapshot.data,
validator: (value) {
if (value == null || value.isEmpty) {
return "Hvem er du?";
}
return null;
},
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Bandit',
prefixIcon: Align(
widthFactor: 1.0,
heightFactor: 1.0,
child: Icon(Icons.person),
),
suffixIcon: Align(
widthFactor: 1.0,
heightFactor: 1.0,
child: Icon(Icons.arrow_drop_down),
)),
),
),
Container(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 30.0),
child: DateTimePicker(
controller: dateController,
validator: (value) {
if (value == null || value.isEmpty) {
setState(() {
dateController.text =
dateFormat.format(DateTime.now()).toString();
});
}
return null;
},
type: DateTimePickerType.date,
dateMask: 'dd-MM-yyyy',
firstDate: DateTime(2020),
lastDate: DateTime(2050),
dateLabelText: 'Dato',
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Dato',
prefixIcon: Align(
widthFactor: 1.0,
heightFactor: 1.0,
child: Icon(Icons.date_range),
)),
),
),
Container(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 30.0),
child: TextFormField(
controller: courseController,
validator: (value) {
if (value == null || value.isEmpty) {
setState(() {
courseController.text = "HJGK";
});
}
return null;
},
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Bane',
prefixIcon: Align(
widthFactor: 1.0,
heightFactor: 1.0,
child: Icon(Icons.golf_course),
)),
),
),
Container(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 30.0),
child: TextFormField(
controller: scoreController,
validator: (value) {
if (value == null || value.isEmpty) {
return "Indtast score";
}
return null;
},
keyboardType: TextInputType.number,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Score',
prefixIcon: Align(
widthFactor: 1.0,
heightFactor: 1.0,
child: Icon(Icons.sports_score)),
),
)),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
shouldDisplay = !shouldDisplay;
}
shouldDisplay
? showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text("Score registreret"),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Padding(
padding:
const EdgeInsets.symmetric(
vertical: 10),
child: Text(
"Spiller: ${nameController.text}"),
),
Padding(
padding:
const EdgeInsets.symmetric(
vertical: 10),
child: Text(
"Dato: ${dateController.text}"),
),
Padding(
padding:
const EdgeInsets.symmetric(
vertical: 10),
child: Text(
"Bane: ${courseController.text}"),
),
Padding(
padding:
const EdgeInsets.symmetric(
vertical: 10),
child: Text(
"Score: ${scoreController.text}"),
),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
)
: null;
},
child: const Text("Submit")),
],
);
}
}
}),
);
}
}
bragi
Updated on January 04, 2023Comments
-
bragi over 1 year
I am fairly new to Flutter and am currently trying to use some data from a database to display in a dropdown select menu (using the mysql1 and select_form_field packages). The
SelectFormField
needs to be passed aList<Map<String, dynamic>>
as itsitems:
-parameter. Whenever I try to run my code I get the exception LateError (LateInitializationError: Field '_items@68190616' has not been initialized.).After looking around it seemed like initializing my item list in
initState()
should do the trick, but I can't get that to work. Below is my main.dart.class MyCustomFormState extends State<MyCustomForm> { ... late List<Map<String, dynamic>> _items; @override void initState() { _getData(); super.initState(); } _getData() async { _items = await getData(); } Widget build(BuildContext context) { return Form( key: _formKey, child: Column( children: <Widget>[ Container( child: SelectFormField( controller: nameController, hintText: "...", items: _items, ... }
And this is my database.dart file which is able to fetch and format the data in the
List<Map<String, dynamic>>
format I need:getData() async { List<Map<String, dynamic>> items = <Map<String, dynamic>>[]; dynamic conn = await connect('database'); var results = await conn.query('select * from data'); for (var row in results) { items.add({'value': row[0], 'label': row[1]}); } await conn.close(); return items; }
Any help is greatly appreciated. Thanks!
-
bragi about 2 yearsCreating an empty one make the app possible to run, but gives this error as soon as I click the
SelectFormField
:_AssertionError ('package:flutter/src/material/popup_menu.dart': Failed assertion: line 877 pos 10: 'items != null && items.isNotEmpty': is not true.)
. Assigning it to _items immediately gives me this error:type 'Future<dynamic>' is not a subtype of type 'List<Map<String, dynamic>>'
, which was an error I was trying to circumvent with this setup. -
George Rabbat about 2 years@simonbrage I have edited the answer to suit the error message. try it and give me your feedback
-
bragi about 2 yearsNow if I assign an empty list for starters,
_items
just remains an empty list. If I assign it immediately, I also have to return_items
in_getData()
, but in the end I end up with this error again:type 'Future<dynamic>' is not a subtype of type 'List<Map<String, dynamic>>'
-
George Rabbat about 2 years@simonbrage did you tried after editing and it gives you the same error? it's impossible to be Future<dynamic> because of the
await
keyword. -
bragi about 2 yearsAh sorry, I misread it. When I do what you suggest I get the following error in
_getDataInit()
:_CastError (type 'Null' is not a subtype of type 'List<Map<String, dynamic>>' in type cast)
-
George Rabbat about 2 yearsso the main error here is inside _getData() method because it return null. debug it and see what's going on there and why it returns null instead of List
-
bragi about 2 yearsYeah. The odd thing is e.g. if I
print(_items)
in_getBandits()
it will have the data I'm looking for, but if Iprint(_items)
ininitState()
after my_getBandits();
call,_items
will evaluate tonull
. -
George Rabbat about 2 yearstry to breakpoint the code and follow the code where it gets null. hit me with the result
-
bragi about 2 yearsHmm, if I do breakpoint at
_getData()
ininitState()
and step into it, it will show_items
asnull
all the way through. But if I print it from_getData()
it will output the correct data. -
George Rabbat about 2 yearson
initState
setprint(_getData().runtimeType);
what the type it gave? -
bragi about 2 yearsIt gives
Future<dynamic>
-
George Rabbat about 2 yearsin my code in the separated method (edited one) put print get data with await with runtime Type. what it yields?
-
bragi about 2 yearsIf I do
print(await _getData().runtimeType
in_getDataInit
I get this error: NoSuchMethodError (NoSuchMethodError: Class 'Future<dynamic>' has no instance getter 'runtimetype'. Receiver: Instance of 'Future<dynamic>' Tried calling: runtimetype). But I get issues withFuture<dynamic>
every time I try to return_items
from_getData()
. -
George Rabbat about 2 yearsTry wrap the code like this
print((await _getData()).runtimeType)
-
bragi about 2 yearsThen it prints
List<Map<String, dynamic>>
. But it is still null when accessing it in my SelectFormField -
George Rabbat about 2 yearsI have Idea, why don't you use FutureBuilder in your build tree? isn't more efficient? If you have Google Drive please send the code at it to help you
-
George Rabbat about 2 years@bragi I've Edited the answer try it. it worked for me
-
George Rabbat about 2 years@bragi Please remove the files from Google Drive for security reasons. And change your Simply.com SQL password. And if it solved you problem accept the answer
-
bragi about 2 yearsOMG. Thanks for that shout, was in a hurry yesterday. Your solution works perfectly, thank you very much!
-
George Rabbat about 2 years@bragi In service. Don't forget to change SQL password
-
bragi about 2 yearsYep, already done. Thanks! :D