Skip to content

Instantly share code, notes, and snippets.

@PlugFox
Created March 7, 2024 20:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save PlugFox/0366eb6d7bd2f3e03fd629c5a96ea8ff to your computer and use it in GitHub Desktop.
Save PlugFox/0366eb6d7bd2f3e03fd629c5a96ea8ff to your computer and use it in GitHub Desktop.
Async expand example
/*
* 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