Saad Ebad
Saad Ebad

Reputation: 226

Stack Overflow error in flutter with no specific errors

i am getting stack overflow and i am unable to fix this issue.when analyzing the errors list i think there is an issue in database_client.dart file i want you to fix it by seeing the code in database_client.dart file which i am providing below. I am going to provide my all code below of different dart files which i am using in my project so that it is easy to find out the existing problem

main.dart

import 'package:flutter/material.dart';
import 'package:no_to_do_app/ui/home.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'NotoDo',
      home: new Home(),
    );
  }
}

home.dart

import 'package:flutter/material.dart';
import 'package:no_to_do_app/ui/notodo_screen.dart';
class Home extends StatelessWidget {
  const Home({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: Text('NoToDo'),
        backgroundColor: Colors.black54,
      ),
      body: new NoToDoScreen(

      )
    );
  }
}

database_client.dart

import 'dart:async';
import 'dart:io';
import 'package:no_to_do_app/model/nodo_item.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

class DatabaseHelper
{
  static final DatabaseHelper _instance = new DatabaseHelper();
  factory DatabaseHelper() => _instance;

  final String tableName = "nodoTbl";
  final String columnId = "id";
  final String columnItemName = "itemName";
  final String columnDateCreated = "dateCreated";

  static late Database _db;

  Future<Database> get database async
  {
    if(_db!=null)
      {
        return _db;
      }
    _db =await initDb();
    return _db;
  }

  DatabaseHelper.internal();

  initDb() async
  {
    Directory documentDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentDirectory.path, "notodo_db.db");
    var ourDb= await openDatabase(path , version: 1 , onCreate: _onCreate);
    return ourDb;
  }

  void _onCreate(Database db, int version) async
  {
   await db.execute(
     "CREATE TABLE $tableName(id INTEGER PRIMARY KEY , $columnItemName TEXT ,$columnDateCreated TEXT)"
   );
   print('Table is Created');
  }

  Future<int> saveItem(NoDoItem item) async
  {
    var dbClient = await database;
    int res =await dbClient.insert("$tableName", item.toMap());
    print(res.toString());
    return res;
  }

  Future<List> getItems() async
  {
    var dbClient = await database;
    var result = await dbClient.rawQuery("SELECT * FROM $tableName ORDER BY $columnItemName ASC");
    return result.toList();
  }

  Future<int?> getCount() async
  {
    var dbClient = await database;
    return Sqflite.firstIntValue(await dbClient.rawQuery(
        "SELECT COUNT(*) FROM $tableName"
    ));
  }

  Future<NoDoItem?> getItem(int id) async{
    var dbClient = await database;
    var result = await dbClient.rawQuery("SELECT * FROM $tableName WHERE id=$id");
    if(result.length==0) return null;
    return new NoDoItem.fromMap(result.first);
  }

  Future<int> deleteItem(int id) async
  {
    var dbClient =await database;
    return await dbClient.delete(tableName,where: "$columnId = ?", whereArgs: [id]);
  }

  Future<int> updateItem(NoDoItem item) async
  {
   var dbClient =await database;
   return await dbClient.update("$tableName", item.toMap(),
   where: "$columnId=?", whereArgs: [item.id]);
  }

  Future close() async
  {
    var dbClient =await database;
    return dbClient.close();
  }
}

nodo_item.dart

import 'package:flutter/material.dart';


class NoDoItem extends StatelessWidget {
  late String _itemName;
  late String _dateCreated;
  late int _id;

  NoDoItem( this._itemName , this._dateCreated);

  NoDoItem.map(dynamic obj)
  {
    _itemName = obj['ItemName'];
    _dateCreated = obj['DateCreated'];
    _id = obj['id'];
  }

  String get itemName => _itemName;
  String get dateCreated => _dateCreated;
  int get id => _id;

  Map<String , dynamic>toMap()
  {
    var map = new Map<String , dynamic>();
    map['ItemName'] = _itemName;
    map['DateCreated'] = _dateCreated;
    if(_id !=null)
      {
        map['id'] = _id;
      }
    return map;
  }

  NoDoItem.fromMap(Map<String , dynamic>map)
  {
    _itemName = map['ItemName'];
    _dateCreated = map['DateCreated'];
    _id = map['id'];
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.all(8.0),
      child: new Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(_itemName ,
          style: new TextStyle(
            color: Colors.white,
            fontSize: 16.5,
            fontWeight: FontWeight.bold
          ),),
          new Container(
            margin: const EdgeInsets.only(top: 5.0),
            child: Text('Created on: $_dateCreated',
              style: TextStyle(
                color: Colors.white70,
                fontStyle: FontStyle.italic,
                fontSize: 13.4
              ),),
          )
        ],
      )
    );
  }
}

notodo_screen

import 'package:flutter/material.dart';
import 'package:no_to_do_app/model/nodo_item.dart';
import 'package:no_to_do_app/util/database_client.dart';

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

  @override
  _NoToDoScreenState createState() => _NoToDoScreenState();
}

class _NoToDoScreenState extends State<NoToDoScreen> {
  TextEditingController _textEditingController = TextEditingController();
  var db = DatabaseHelper();

  void _hndleSubmitted(String text) async
  {
    _textEditingController.clear();
    NoDoItem noDoItem = new NoDoItem(text,DateTime.now().toIso8601String());
    int savedItemId = await db.saveItem(noDoItem);

    print("Item saved ID: $savedItemId");
  }

  @override
  Widget build(BuildContext context) {
    return  Scaffold(
      backgroundColor: Colors.black87,
      body:  Column(),
      floatingActionButton:  FloatingActionButton(
          tooltip: 'Add Item',
          backgroundColor: Colors.redAccent,
          child:  const ListTile(
              title:  Icon(Icons.add)
          ),
          onPressed: _showFormDialog),

    );

  }

  void _showFormDialog() {
    var alert = AlertDialog(
      content: Row(
        children: [
          Expanded(
            child: TextField(
              controller: _textEditingController,
              autofocus: true,
              decoration: InputDecoration(
                labelText: 'item',
                hintText: "eg. Don't buy Stuff",
                icon: Icon(Icons.add_circle_outline_outlined)
              ),
            ))
        ],
      ),
          actions:[
            TextButton(
              style: ButtonStyle(
        foregroundColor: MaterialStateProperty.all<Color>(Colors.blue),
    ),
    onPressed: ()
    {
    _hndleSubmitted(_textEditingController.text);
    _textEditingController.clear();
    },
    child: Text("Save"),
            ),

            TextButton(
              style: ButtonStyle(
            foregroundColor: MaterialStateProperty.all<Color>(Colors.blue),
            ),
            onPressed:() => Navigator.pop(context),
            child: Text("Cancel"),)
          ]
    );
    showDialog(context: context,
    builder:(_)
    {
      return alert;
    });
  }
}

errors list

======== Exception caught by widgets library =======================================================
The following StackOverflowError was thrown building _BodyBuilder:
Stack Overflow

The relevant error-causing widget was: 
  Scaffold Scaffold:file:///C:/Users/SAAD%20EBAD.SAAD_EBAD/IdeaProjects/no_to_do_app/lib/ui/home.dart:8:16
When the exception was thrown, this was the stack: 
#0      DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart:11:31)
#1      DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart)
#2      new DatabaseHelper (package:no_to_do_app/util/database_client.dart:12:31)
#3      DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart:11:47)
#4      DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart)
#5      new DatabaseHelper (package:no_to_do_app/util/database_client.dart:12:31)
#6      DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart:11:47)
#7      DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart)
#8      new DatabaseHelper (package:no_to_do_app/util/database_client.dart:12:31)
#9      DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart:11:47)
#10     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart)
#11     new DatabaseHelper (package:no_to_do_app/util/database_client.dart:12:31)
#12     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart:11:47)
#13     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart)
#14     new DatabaseHelper (package:no_to_do_app/util/database_client.dart:12:31)
#15     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart:11:47)
#16     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart)
#17     new DatabaseHelper (package:no_to_do_app/util/database_client.dart:12:31)
#18     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart:11:47)
#19     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart)
#20     new DatabaseHelper (package:no_to_do_app/util/database_client.dart:12:31)
#21     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart:11:47)
#22     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart)
#23     new DatabaseHelper (package:no_to_do_app/util/database_client.dart:12:31)
#24     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart:11:47)
#25     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart)
#26     new DatabaseHelper (package:no_to_do_app/util/database_client.dart:12:31)
#27     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart:11:47)
#28     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart)
#29     new DatabaseHelper (package:no_to_do_app/util/database_client.dart:12:31)
#30     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart:11:47)
#31     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart)
#32     new DatabaseHelper (package:no_to_do_app/util/database_client.dart:12:31)
#33     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart:11:47)
#34     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart)
#35     new DatabaseHelper (package:no_to_do_app/util/database_client.dart:12:31)
#36     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart:11:47)
#37     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart)
#38     new DatabaseHelper (package:no_to_do_app/util/database_client.dart:12:31)
#39     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart:11:47)
#40     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart)
#41     new DatabaseHelper (package:no_to_do_app/util/database_client.dart:12:31)
#42     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart:11:47)
#43     DatabaseHelper._instance (package:no_to_do_app/util/database_client.dart)
...
...
...     Normal element mounting (21 frames)
#4427   Element.inflateWidget (package:flutter/src/widgets/framework.dart:3673:14)
#4428   Element.updateChild (package:flutter/src/widgets/framework.dart:3425:18)
#4429   RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1198:16)
#4430   RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:1167:5)
#4431   RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> (package:flutter/src/widgets/binding.dart:1112:18)
#4432   BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2573:19)
#4433   RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:1111:13)
#4434   WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:944:7)
#4435   WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> (package:flutter/src/widgets/binding.dart:924:7)
(elided 11 frames from class _RawReceivePortImpl, class _Timer, dart:async, and dart:async-patch)
====================================================================================================

Upvotes: 1

Views: 1737

Answers (1)

h8moss
h8moss

Reputation: 5030

Here is what I believe is happening:

static final DatabaseHelper _instance = new DatabaseHelper();
factory DatabaseHelper() => _instance;

when you initialize _instance, you call DatabaseHelper, which calls _instance, which calls DatabaseHelper, and so on and so forth until you get a stack overflow.

to fix this, simply create a private initializer for the instance:

static final DatabaseHelper _instance = DatabaseHelper._private();
DatabaseHelper._private();
factory DatabaseHelper() => _instance;

I would also make the factory a getter, but that is more of a preference thing I believe.

Upvotes: 2

Related Questions