-
Hello everyone, I'm trying to update a view in real time with a Stream. The Stream contains a list with objects which are created through a many to many relationship. This is the code (I've used similar code to return this list as a Future): Stream<List<TrainingPlanEntity>> watchAllTrainingPlans(
{bool custom = false}) async* {
Map<int, TrainingPlanEntity> trainingPlansMap = {};
var planQuery = (select(trainingPlans)
..where((tbl) => tbl.custom.equals(custom)))
.watch();
await for (final row in planQuery) {
for (final entry in row) {
final plan = TrainingPlanEntity(
id: entry.id,
title: entry.title,
position: toPositionEnum(entry.position),
exercises: []);
trainingPlansMap.putIfAbsent(entry.id, () => plan);
}
}
// I never reach this line because I use await in the for loop and I don't yield anything but I'm not sure how to solve it.
var joinQuery = select(trainingPlanExercises).join([
innerJoin(
exercises, exercises.id.equalsExp(trainingPlanExercises.fkExercise))
]).watch();
await for (var row in joinQuery) {
for (var entry in row) {
final exercise = entry.readTable(exercises);
final planExerciseTable = entry.readTable(trainingPlanExercises);
if (trainingPlansMap.containsKey(planExerciseTable.fkPlan)) {
trainingPlansMap[planExerciseTable.fkPlan]!.exercises.add(
ExerciseEntity(
id: exercise.id,
title: exercise.title,
descriptions: [],
amount: planExerciseTable.repetitions,
position: exercise.position));
}
}
}
yield trainingPlansMap.values.toList();
} Thanks for helping! :) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
So the thing about Looking at your code, it looks like you want to combine the the Stream<List<TrainingPlanEntity>> watchAllTrainingPlans({bool custom = false}) {
var planQuery = (select(trainingPlans)
..where((tbl) => tbl.custom.equals(custom)))
.watch();
var joinQuery = select(trainingPlanExercises).join([
innerJoin(
exercises, exercises.id.equalsExp(trainingPlanExercises.fkExercise))
]).watch();
return Rx.combineLatest2<TrainingPlan, TypedResult, List<TrainingPlanEntity>>(
planQuery, joinQuery, (plans, joins) {
Map<int, TrainingPlanEntity> trainingPlansMap = {};
for (final entry in plans) {
final plan = TrainingPlanEntity(
id: entry.id,
title: entry.title,
position: toPositionEnum(entry.position),
exercises: []);
trainingPlansMap.putIfAbsent(entry.id, () => plan);
}
for (var entry in joins) {
final exercise = entry.readTable(exercises);
final planExerciseTable = entry.readTable(trainingPlanExercises);
if (trainingPlansMap.containsKey(planExerciseTable.fkPlan)) {
trainingPlansMap[planExerciseTable.fkPlan]!.exercises.add(
ExerciseEntity(
id: exercise.id,
title: exercise.title,
descriptions: [],
amount: planExerciseTable.repetitions,
position: exercise.position));
}
}
return trainingPlansMap.values.toList();
});
}
|
Beta Was this translation helpful? Give feedback.
So the thing about
await for
it is that it keeps going until the stream is done. With drift, you get a never-ending stream of snapshots, so theawait for
will never complete (well, until the database is closed, but that's not helpful).Looking at your code, it looks like you want to combine the the
planQuery
and thejoinQuery
streams into one. For this purpose, I suggest using helpers from the rxdart package: