Home > front end >  Flutter - LateError (LateInitializationError: Field '_items@68190616' has not been initial
Flutter - LateError (LateInitializationError: Field '_items@68190616' has not been initial

Time:05-09

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 a List<Map<String, dynamic>> as its items:-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!

CodePudding user response:

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")),
                  ],
                );
              }
            }
          }),
    );
  }
}
  • Related