Flutter Tutorial: Building An Expense Manager App – 5

This is the fifth part of Flutter tutorial series where we are building an Expenses Manager app.

Introduction

We have already created functionalities to create new category and get all categories previously. Now, in this part of the complete Flutter tutorial series, we will add features for:

  • Deleting category item from a list
  • Built Value model for expense
  • Add migration on existing sqlite database

Deleting Category Item

In order to delete a category item, now we need to:

DecisionMentor app
  • Add a method to delete it from our Sqlite database
  • Create a method in Category BLoC to call delete
  • Add a delete feature from Category ListView

We will start from the top.

Delete Item From Sqlite/Sqflite Database In Flutter

Create a method deleteCategory in the CategoryService. It takes categoryId as parameter to search and delete item from database.

...
abstract class CategoryServiceBase {  
  Future<BuiltList<CategoryModel>> getAllCategories();
  Future<int> createCategory(CategoryModel category);
  Future<int> deleteCategory(int categoryId);
}

class CategoryService implements CategoryServiceBase {

  @override
  Future<int> deleteCategory(int categoryId) async {
    var db = await OfflineDbProvider.provider.database;
    var result = db.delete("Category", where: "id = ?", whereArgs: [categoryId]);
    return result;
  }

  @override
...

Call Delete From CategoryBloc

Next, create a method to call the delete function from CategoryBloc. After category item has been deleted, we want to re-create the category list. So, we will also do that.

 Future<void> deleteCategory(int categoryId) async {
    await categoryService.deleteCategory(categoryId).then((value) {
      //re- create list after delete
      getCategories();
    });
  }

Delete Functionality On ListView

Now that we have everything in place for category deletion, all that needs to be done is add a delete button. For this purpose, we can make use of the trialing property of ListTile widget. We will add a delete button and call the delete method of underlying CategoryBloc.

ListTile(
  onTap: () {},
  leading: Icon(
	IconData(category.iconCodePoint,
		fontFamily: 'MaterialIcons'),
	color: Theme.of(context).accentColor,
  ),
  trailing: IconButton(
	icon: Icon(Icons.delete),
	color: Theme.of(context).primaryColorLight,
	onPressed: () => _categoryBloc.deleteCategory(category.id),
  ),
Delete Category Item From ListView
Delete Category Item From ListView

Benefit Of Using StreamBuilder With BLoC Pattern In Flutter

As you can see, once an item is deleted, the category list is instantly re-created. This is one of the benefits of using StreamBuilder widget with BLoC Pattern in flutter. Since, the category list is listening to a Stream from CategoryBloc, it instantly re-builds once the stream is updated.

We do not have to update the UI programmatically!

Built Value Model For Expense

We have completed the features needed for Category in our Expense Manager. Now, we will develop features for managing expenses. We will start by creating an Expense model which will also be a built value type model.

Create a file “expense_model.dart” inside the “models” folder.

import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';

part 'expense_model.g.dart';

abstract class ExpenseModel
    implements Built<ExpenseModel, ExpenseModelBuilder> {
  ExpenseModel._();
  factory ExpenseModel([updates(ExpenseModelBuilder b)]) = _$ExpenseModel;
  static Serializer<ExpenseModel> get serializer => _$expenseModelSerializer;

  @nullable
  int get id;
  @nullable
  int get categoryId;
  @nullable
  String get title;
  @nullable
  String get notes;
  @nullable
  double get amount;
}

The ExpenseModel has fields for title, notes and amount. It also has reference to the categoryId to link with any category item.

Add the ExpenseModel to the serializers list.

@SerializersFor(const [
  CategoryModel,
  ExpenseModel
])

Finally, auto-generate the remaining part of built value code by calling the command below:

flutter pub run build_runner build

Adding Migrations To Add Expense Table In Database

We have already created the necessary infrastructure to add new migrations on top of the sqlite database in our Flutter app.

First, we add a script to generate Expense table in the “init_db.dart” file.

const String createExpenseDbScript = """
  CREATE TABLE EXPENSE (
      id INTEGER PRIMARY KEY,
      categoryId INTEGER, 
      title TEXT,
      notes TEXT,
      amount REAL
      );
    """;

Then, add migration in the DbMigrator class.

import 'package:expense_manager/db/migrations/init_db.dart';

class DbMigrator {
  static final Map<int, String> migrations = {
    1: initDbScript,
    2: createExpenseDbScript,
  };
}

That’s all the code we need to write for creating migrations. The Sqlite database gets updated when we re-run the application.

Wrapping Up

In this part of our Flutter tutorial, we added a functionality to remove category item. Then we create Expense model and added table for the model in offline database. In the next part, we will add features to create and view expenses by category.

Links To Other Parts Of This Flutter Tutorial Series

GitHub Link

Checkout the entire project from GitHub.

Similar Tutorial Series:

Build HangMan Game In Flutter