watchSyllabus method
Watches the syllabus authored by teacherId for offering offeringId,
refreshing it once per subscription (no staleness gate).
Emits the cached row immediately when present, then refreshes in the
background; with no cached row it blocks on the first fetch instead, so
the UI shows content (or a definitive "no syllabus") rather than flashing
empty. The stream re-emits when the DB is updated. Emits null when the
teacher hasn't submitted a syllabus (尚未登錄) or is unknown.
Implementation
Stream<Syllabus?> watchSyllabus({
required int offeringId,
required String teacherId,
}) async* {
final teacher = await (_database.select(
_database.teachers,
)..where((t) => t.code.equals(teacherId))).getSingleOrNull();
if (teacher == null) {
yield null;
return;
}
final query = _database.select(_database.syllabuses)
..where(
(s) =>
s.courseOffering.equals(offeringId) & s.teacher.equals(teacher.id),
);
// Fetch once per subscription. The guard stops the refresh's own write
// from re-triggering the fetch on the re-emit.
var refreshed = false;
await for (final syllabus in query.watchSingleOrNull()) {
if (syllabus == null && !refreshed) {
refreshed = true;
try {
await refreshSyllabus(offeringId: offeringId, teacherId: teacherId);
// Emit the freshly fetched row (or null on 尚未登錄) rather than the
// stale null snapshot, before the stream re-emits.
yield await query.getSingleOrNull();
continue;
} catch (_) {
// Absorb: yield null below so the UI exits its loading state
}
}
yield syllabus;
if (syllabus != null && !refreshed) {
refreshed = true;
try {
await refreshSyllabus(offeringId: offeringId, teacherId: teacherId);
} catch (_) {
// Absorb: stale content is shown via stream
}
}
}
}