Implement asyncSwitchMap
xzhorikx opened this issue · comments
If would be handy to have something like asyncSwitchMap
in this package.
Use case
Creation of the child stream requires asynchronous code execution.
Example:
Loading user's items from the database. UI must react on changes in both user info stream and item info stream.
/// Provider interface for database
abstract class Provider {
Furure<T> provide();
}
/// Abstract database class
abstract class Database {
Stream<UserItem> findByUserId(String userId);
}
/// Item repository
class ItemRepository {
...
Stream<UserItem> findByUserId(Stream<User> userStream) {
userStream
.swtichMap((User user){
/// Database needs to be accessed with `await` keyword. Currently it is not possible to achieve this syntax with switchMap()
Database db = await _databaseProvider.provide();
return db.findbyUserId(user.id);
});
}
}
If this implementation is possible, it would be really nice to have it in order to make code cleaner.
If you have a Future<Stream>
you can convert to a Stream
with StreamCompleter.fromFuture
. https://pub.dev/documentation/async/latest/async/StreamCompleter/fromFuture.html
The behavior difference depends on whether you hope for the output stream to wait to start listening on the subsequent stream until after the Future
has completed, while still emitting events from the previous one. That behavior isn't possible today with StreamCompleter
and switchLatest
or switchMap
, but from what I can tell I don't think you'd want that behavior. (I'm also curious why findByUserId
returns a Stream
instead of a Future
, but that's unrelated to the immediate problem).
class ItemRepository {
Stream<UserItem> findByUserId(Stream<User> userStream) {
userStream
.map((user) async {
final db = await _databaseProvider.provide();
return db.findbyUserId(user.id);
})
.map(StreamCompleter.fromFuture)
.switchLatest();
}
}