Mustafa RECEPOGLU
Mustafa RECEPOGLU

Reputation: 41

Flutter LateInitializationError

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sqflite_demo/data/dbHelper.dart';
import 'package:sqflite_demo/models/product.dart';


class ProductAdd extends StatefulWidget {
  const ProductAdd({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return ProductAddState();
  }
}

class ProductAddState extends State with DbHelper{

  var  Dbhelper = DbHelper();
  var txtName = TextEditingController();
  final txtDescription = TextEditingController();
  var txtUnitPrice = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      appBar: AppBar(
        title: const Text("Yeni Ürün ekle"),
      ),
      body: Padding(
        padding: EdgeInsets.all(30.0),
        child: Column(
          children: <Widget>[
            buildNameField(),
            buildDescriptionField(),
            buildUnitPriceField(),
            buildSaveButton()
          ],
        ),
      ),
    );
  }

  buildNameField() {
    return TextField(
      decoration: const InputDecoration(labelText: "Ürün adı", hintText: "Tohum"),
      controller: txtDescription,
    );
  }

  buildDescriptionField() {
    return TextField(
      decoration: const InputDecoration(
          labelText: "Ürün açıklaması", hintText: "Domates"),
      controller: txtUnitPrice,
    );
  }
  buildUnitPriceField() {
    return TextField(
      keyboardType: TextInputType.number,
      inputFormatters: <TextInputFormatter>[
        FilteringTextInputFormatter.digitsOnly
      ],
      decoration: const InputDecoration(labelText: "Birim fiyatı", hintText: "20"),
      controller: txtName,
    );
  }


  buildSaveButton() {
    return FlatButton(
      onPressed: () {
        addProduct();
      },
      child: const Text("Ekle"),
    );
  }

  void addProduct() async {
    var result = await Dbhelper.insert(Product(name: txtName.text, description: txtDescription.text, unitPrice: double.tryParse(txtUnitPrice.text)));
    Navigator.pop(context,true);
  }
}

import 'dart:async';

import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

import '../models/product.dart';


class DbHelper {

  Database ?_db;
  static final DbHelper instance=DbHelper();
  Future<Database> get db async{
    if(_db==null){
      _db=await initializedb();
    }
    return _db!;
  }

  Future<Database> initializedb()async {
    String dbPath = join(await getDatabasesPath(),"etrade.db");
    var etradeDB = await openDatabase(dbPath,version: 1,onCreate: createDb);
    return etradeDB;
  }

  void createDb(Database db, int version)async {
    await db.execute("Create table products(id integer primary key, name text, description text, unitPrice integer)");
  }

  Future<List<Product>> getProducts() async{
    Database db = await this.db;
    var result = await db.query("products");
    return List.generate(result.length, (i){
      return Product.fromObject(result[i]);
    });


  }
  Future<int> insert(Product product) async {
    Database db = await this.db;
    var result = await db.insert("products",product.toMap());
    return result;
  }

  Future<int> delete(int id) async {
    var db = await this.db;
    var result = await db.rawDelete("delete from products where id=$id");
    return result;
  }

  Future<int> update(Product product) async {
    var db = await this.db;
    var result = await db.update("product", product.toMap(), where: "id=?",whereArgs: [product.id]);
    return result;
  }

}

class Product {
  late int ?id;
  late String name;
  late String description;
  late double? unitPrice;

  Product(
      {required this.name, required this.description, required this.unitPrice});
  Product.withID(
      {required this.id, required this.name, required this.description, required this.unitPrice});

  Map<String,dynamic> toMap(){

    var map  = Map<String,dynamic>();
    map["name"]=name;
    map["description"]=description;
    map["unitPrice"]=unitPrice;
    var id = this.id;
    if(id!=null){
      map["id"]=id;
    }
    return map;
  }

  Product.fromObject(dynamic o){
    this.id=int.tryParse(o["id"])! ;
    this.name=o["name"];
    this.description=o["description"];
    this.unitPrice=double.tryParse(o["unitPrice"].toString())! ;
  }
}

here is erros mes. E/flutter ( 6166): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: LateInitializationError: Field 'id' has not been initialized. E/flutter ( 6166): #0 Product.id (package:sqflite_demo/models/product.dart) E/flutter ( 6166): #1 Product.toMap (package:sqflite_demo/models/product.dart:18:19) E/flutter ( 6166): #2 DbHelper.insert (package:sqflite_demo/data/dbHelper.dart:41:53) E/flutter ( 6166): E/flutter ( 6166): #3 ProductAddState.addProduct (package:sqflite_demo/screens/prosuct_add.dart:80:18) E/flutter ( 6166): E/flutter ( 6166):

Upvotes: 0

Views: 201

Answers (1)

pblead26
pblead26

Reputation: 810

As @Ber mentioned, there is no need to combine late with a nullable variable. Let it remain a nullable variable only, and remove the late keyword.

class Product {
  int? id;
...

This is from the docs :

The late modifier lets you defer initialization, but still prohibits you from treating it like a nullable variable.

I reproduced the error in Dartpad with this code, and removed late keyword and made the code work again.

void main() {
  Product product = Product(name: "someName", description: "someDesc", unitPrice: 44);
  product.toMap();
}


class Product {
  int? id;
  late String name;
  late String description;
  late double? unitPrice;

  Product(
      {required this.name, required this.description, required this.unitPrice});
  Product.withID(
      {required this.id, required this.name, required this.description, required this.unitPrice});

  Map<String,dynamic> toMap(){

    var map  = Map<String,dynamic>();
    map["name"]=name;
    map["description"]=description;
    map["unitPrice"]=unitPrice;
     var id = this.id;
    if( id!=null){
      map["id"]=id;
    }
    return map;
  }

  Product.fromObject(dynamic o){
    this.id=int.tryParse(o["id"])! ;
    this.name=o["name"];
    this.description=o["description"];
    this.unitPrice=double.tryParse(o["unitPrice"].toString())! ;
  }
}

If this is not working, maybe you have a different error after removing late?, please share that too.

Upvotes: 1

Related Questions