I'm having problems waiting for a Future result. I have a function that returns a Future, I call it using await function, but the result I get back is always null even though the debug says it isn't null. This is all driven by the click of a button.
First the button:
new FilledButton(
child: Text('Copy ${Config.dance}'),
onPressed: () async
{
NamePos? np = await DancePage.getDanceName (context, dance.name + " - Copy", dance.numDancers, dance.numMusicians) ;
if (np != null && np.name.isNotEmpty && np.numPos > 0)
{
// Make a copy of the position names
List<String> pos = List<String>.filled(np.numPos + np.numMusicians, "") ;
for (int i = 0 ; i < np.numPos ; ++i)
{
if (i < dance.numDancers)
pos[i] = dance.positionsNames[i] ;
else
pos[i] = (i + 1).toString() ;
}
int m = 1 ;
int p = dance.numDancers ;
for (int i = np.numPos ; i < pos.length ; ++i, ++m, ++p)
{
if (p < dance.numPositions)
pos[i] = dance.positionsNames[p] ;
else
pos[i] = "Musician " + m.toString() ;
}
// Create a new dance based on the source one
Dance? nd = await DBServer.instance.addDance(np.name, np.numPos, pos, dance.note);
if (nd != null)
{
// copy dancer positions
debugPrint ("Copying dancers") ;
for (Dancer a in Dancer.allDancers(true, Dancer.sBoth))
{
if (a.canDoDance (dance.id))
{
DancePositions pos = new DancePositions(nd.numPositions) ;
List<int> can = a.getPositions (dance.id)!.getAllPositions () ;
for (int p = 0 ; p < nd.numPositions && p < dance.numPositions ; ++p)
{
if (can[p] > 0)
{
pos.setPosition(p, can[p]) ;
}
}
a.setPositions(nd.id, pos) ;
await DBServer.instance.addDancerPositions(a, nd.id);
}
}
}
else
debugPrint ("addDance returned null") ;
Dance.notify() ;
Navigator.of(context).pop(null);
}
}),
The bit that is going wrong is the call to addDance. This always prints the debug "addDance returned null"
This is the addDance function:
Future<Dance?> addDance (String name, int numDancers, List<String> positions, String note) async
{
debugPrint ("Add dance $name") ;
Database db = (await database)! ;
await db.transaction((txn) async
{
var raw = await txn.rawInsert('INSERT INTO dances (name, numPlaces, active, note) VALUES (?,?,?,?)', [name,numDancers,1,note] ) ;
int id = raw.toSigned(64);
if (id > 0)
{
StringBuffer sql = new StringBuffer ("INSERT INTO positions (dance, position, name) VALUES ") ;
bool first = true ;
for (int i = 0 ; i < positions.length ; ++i)
{
if (first)
first = false ;
else
sql.write (", ") ;
sql.write ("($id,$i,'") ;
sql.write (positions[i]) ;
sql.write ("')") ;
}
// debugPrint (sql) ;
await txn.rawInsert (sql.toString ()) ;
Dance d = new Dance (id, name, numDancers, true, note) ;
d.positionsNames = positions ;
debugPrint ("Created dance id $id") ;
d == null ? debugPrint ("dance null") : debugPrint ("dance not null") ;
return d ;
}
else
return null ;
}) ;
return null ;
}
The debug I get looks something like:
I/flutter (14661): Created dance id 36
I/flutter (14661): dance not null
D/InsetsController(14661): show(ime(), fromIme=true)
I/flutter (14661): addDance returned null
Can anyone suggest what I'm doing wrong?
I think you're missing a return
here:
await db.transaction((txn) async
So while your transaction closure returns a result, the top-level code in addDance
doesn't return that to the caller.
To fix that:
return await db.transaction((txn) async