Search code examples
flutterdartfuturesqflite

How To Convert a Future<double> to a double in Flutter/Dart?


Thank you in advance for your help. Futures always mess with my head.

These two doubles are variables in my stateful widget screen.

double _totalExpenses;
double _totalExpensesForBudget;

I have a Sqflite db with two methods which retrieve two separate sums:

Future getTotalExpensesForBudget(int budgetId) async {
final db = await database;
var totalExpensesForBudget = await db.rawQuery('SELECT SUM(Amount) FROM TRANSACTIONS WHERE Budget_id = $budgetId');
return totalExpensesForBudget[0]['SUM(Amount)'];
}

Future getTotalExpenses() async {
final db = await database;
var totalExpenses = await db.rawQuery('SELECT SUM(Amount) FROM Transactions');
return totalExpenses[0]['SUM(Amount)'];
}

In my stateful Flutter screen I have a method that calls both of the Sqflite methods and assign the returned values to the two doubles I declared above:

Future<double> getExpensePercentage(int budgetId) async {
_totalExpenses = await DbHelper.db.getTotalExpenses();
_totalExpensesForBudget = await DbHelper.db.getTotalExpensesForBudget(budgetId);
return (_totalExpensesForBudget / _totalExpenses);
}

In my Widget build method I need to pass the getExpensePercentage(int budgetId) methods returned value to my stateful widget named BudgetCard. The percentOfExpenses: parameter from my BudgetCard stateful widget is expecting a double.

@override
Widget build(BuildContext context) {
getBudgets();
return Column(
  children: <Widget>[
    Image(
      fit: BoxFit.fill,
      image: AssetImage('images/skeemaplaceholder.jpg'),
    ),
    Expanded(
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: ListView.separated(
          itemCount: _budgets.length,
          itemBuilder: (BuildContext context, int index) {
            return BudgetCard(
              icon: IconData(_budgets[index].icon, fontFamily: 'MaterialIcons'),
              name: _budgets[index].name,
              budgetBalance: _budgets[index].budgetBalance,
              budgetAmount: _budgets[index].budgetAmount,
              percentOfTotalBudget: (_budgets[index].budgetAmount / _budgetTotal) * 100,
              percentOfExpenses: 10,
              onPressed: (value) {
                switch (value) {
                  case 'Edit':
                    {
                      _action = 'Edit';
                      _id = _budgets[index].id;
                      _name = _budgets[index].name;
                      _icon = IconData(_budgets[index].icon, fontFamily: 'MaterialIcons');
                      _budgetBalance = _budgets[index].budgetBalance;
                      _isPrimary = _budgets[index].isPrimary;
                      goToBudgetActionScreen(context);
                      break;
                    }
                  case 'Transfer':
                    {
                      break;
                    }
                  case 'Delete':
                    {
                      if (_budgets[index].id == 3) {
                        Scaffold.of(context).showSnackBar(SnackBar(content: Text('Default budget cannot be deleted.')));
                      } else {
                        showDialog(
                          context: context,
                          barrierDismissible: false,
                          builder: (BuildContext context) {
                            return AlertDialog(
                              title: Text(
                                'Are you sure? This action cannot be undone.',
                                style: TextStyle(fontSize: 16),
                              ),
                              actions: <Widget>[
                                FlatButton(
                                  child: Text('Yes'),
                                  onPressed: () {
                                    deleteBudget(_budgets[index].id);
                                    Navigator.pop(context);
                                  },
                                ),
                                FlatButton(
                                  child: Text('Cancel'),
                                  onPressed: () => Navigator.pop(context),
                                ),
                              ],
                            );
                          },
                        );
                        break;
                      }
                    }
                }
              },
            );
          },
          separatorBuilder: (BuildContext context, int index) {
            return Divider();
          },
        ),
      ),
    ),
    Padding(
      padding: EdgeInsets.only(bottom: 4),
    ),
    Center(
      child: FlatButton(
        color: Colors.red,
        textColor: Colors.white,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(20),
        ),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            const Icon(Icons.add_circle),
            Padding(
              padding: const EdgeInsets.fromLTRB(8, 0, 0, 0),
              child: const Text(
                'New Budget',
              ),
            ),
          ],
        ),
        onPressed: () {
          goToBudgetActionScreen(context);
        },
      ),
    ),
  ],
);
}

class BudgetCard extends StatefulWidget {
final IconData icon;
final String name;
final double budgetBalance;
final double budgetAmount;
final double percentOfTotalBudget;
final double percentOfExpenses;
final Function(String) onPressed;

BudgetCard({this.icon, this.name, this.budgetBalance, this.budgetAmount, this.percentOfTotalBudget, this.percentOfExpenses, this.onPressed});

My editor is telling me "The argument type 'Future' can't be assigned to the parameter type 'double'. How in the world do I parse/convert that Future as a double to pass to BudgetCard?

Thanks again.


Solution

  • you can set the future value to the double variable by requesting the function and add then() at the end of it.

    DbHelper.db.getTotalExpenses().then((value)=>{
     _totalExpenses = value
    })
    

    this will change the future to double.