here is a popup screen to add the transaction to the app, as you can see here

popup screen to add data

and when the add button pressed the data will add to database and also to the dislpay , here is the code

ElevatedButton(
              //on pressed
              onPressed: () async {
                final _categoryName = _nameEditingController.text;
                if (_categoryName.isEmpty) {
                  return;
                }

                final _type = selectedCategoryNotifier.value;
                //sending the data to model class
                final _category = CategoryModel(
                  id: DateTime.fromMillisecondsSinceEpoch.toString(),
                  name: _categoryName,
                  type: _type,
                );
                //inserting the data to database
                await CategoryDb.instance.insertCategory(_category);
                //refreshing the ui 
                await CategoryDb.instance.refreshUI();
                //and quitting the popup screen
                Navigator.of(ctx).pop();
              },
              child: const Text('Add'),

            ),

and in this code you can see that I called 2 functions that for insert data and also refresh the UI, in the refresh UI function I added the function that to get all data from database to screen, here the code of all functions for CRUD operatins

const databaseName = 'category-database';

abstract class CategoryDbFunctions {
  Future<List<CategoryModel>> getCategories();
  Future<void> insertCategory(CategoryModel value);
}

//CRUD operations code

class CategoryDb implements CategoryDbFunctions {
  CategoryDb._internal();
  static CategoryDb instance = CategoryDb._internal();
  factory CategoryDb() {
    return instance;
  }

  ValueNotifier<List<CategoryModel>> incomeCategoryListListener =
      ValueNotifier([]);
  ValueNotifier<List<CategoryModel>> expenseCategoryListListener =
      ValueNotifier([]);

  @override
  Future<void> insertCategory(CategoryModel value) async {
    final _categoryDB = await Hive.openBox<CategoryModel>(databaseName);
    await _categoryDB.add(value);
    await refreshUI();
  }

  @override
  Future<List<CategoryModel>> getCategories() async {
    final _categoryDB = await Hive.openBox<CategoryModel>(databaseName);
    return _categoryDB.values.toList();
  }

  Future<void> refreshUI() async {
    final _allCategories = await getCategories();
    incomeCategoryListListener.value.clear();
    expenseCategoryListListener.value.clear();
    await Future.forEach(
      _allCategories,
      (CategoryModel category) {
        if (category.type == CategoryType.income) {
          incomeCategoryListListener.value.add(category);
        } else {
          expenseCategoryListListener.value.add(category);
        }
      },
    );
  }
}

so I checked the all things , but I couldn't find where I'm missing parts,

and here is the main part, it is adding to the database also displaying after I refresh the UI or change the tab here you can see what I mean by 'changing the tab' enter image description here

this is the problem I'm trying to fix this for 2 day, i couldn't find any solution or mistake in my code


Solution 1: Ahmad Abdullah

There many ways you can handle this problem.

but I dont see where you notify youre ui that the data has been changed, flutter does only update the ui when you use setState etc.. these functions help flutter updating the ui where the data changed.

i would recommend you to use setState in the place you invoke youre dialog.

    onTap:(){
       setState(){
          await dialogStuff();
       }
    }