Created
March 7, 2024 20:07
-
-
Save PlugFox/0366eb6d7bd2f3e03fd629c5a96ea8ff to your computer and use it in GitHub Desktop.
Async expand example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Stream async expand | |
* https://gist.github.com/PlugFox/0366eb6d7bd2f3e03fd629c5a96ea8ff | |
* https://dartpad.dev?id=0366eb6d7bd2f3e03fd629c5a96ea8ff | |
* Mike Matiunin <plugfox@gmail.com>, 07 March 2024 | |
*/ | |
import 'dart:async'; | |
import 'package:flutter/material.dart'; | |
typedef Product = String; | |
typedef Property = String; | |
typedef Row = ({Product product, List<Property> properties}); | |
final List<Row> data = <Row>[ | |
(product: 'banana', properties: ['yellow', 'tasty', 'long']), | |
(product: 'apple', properties: ['red', 'juicy']), | |
(product: 'cherry', properties: ['red', 'sweet', 'small']), | |
]; | |
void main() { | |
final state = <Product, Row>{}; | |
Future<void> delay([int ms = 1000]) => Future<void>.delayed(Duration(milliseconds: ms)); | |
final stream = Stream<Row>.fromIterable(data) | |
.asyncExpand((e) async* { | |
yield (product: e.product, properties: <Property>[]); | |
for (var i = 0; i < e.properties.length; i++) { | |
await delay(); | |
yield (product: e.product, properties: e.properties.sublist(0, i + 1)); | |
} | |
}) | |
.map((row) => state..[row.product] = row) | |
.map((state) => state.values.toList(growable: false)); | |
runZonedGuarded<void>( | |
() => runApp(App(stream: stream)), | |
(error, stackTrace) => print('Top level exception: error\nstackTrace'), // ignore: avoid_print | |
); | |
} | |
class App extends StatelessWidget { | |
const App({required this.stream, super.key}); | |
final Stream<List<Row>> stream; | |
@override | |
Widget build(BuildContext context) => MaterialApp( | |
title: 'Async Expand Example', | |
theme: ThemeData.dark(), | |
home: Scaffold( | |
appBar: AppBar( | |
title: const Text('Async Expand Example'), | |
), | |
body: SafeArea( | |
child: StreamBuilder<List<Row>>( | |
stream: stream, | |
builder: (context, snapshot) { | |
final data = snapshot.data ?? <Row>[]; | |
return ListView.builder( | |
itemCount: data.length, | |
itemBuilder: (context, index) { | |
final row = data[index]; | |
return ListTile( | |
title: Text(row.product), | |
subtitle: Text('[${row.properties.join(', ')}]'), | |
); | |
}, | |
); | |
}, | |
), | |
), | |
), | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment