https://github.com/hoc081098/stream_loader
🍂 A Flutter plugin for loading content asynchronously with Dart stream and RxDart. RxDart loader bloc. Reactive loader bloc. Simple reactive state management container - https://pub.dev/packages/stream_loader
https://github.com/hoc081098/stream_loader
bloc-architecture bloc-pattern bloc-pattern-rxdart bloc-rxdart flutter-bloc flutter-bloc-pattern flutter-bloc-pattern-rxdart flutter-bloc-patterns flutter-bloc-rxdart flutter-bloc-sample flutter-reactive flutter-rx flutter-rxbus flutter-rxdart flutter-stream rxdart rxdart-flutter stream-loader
Last synced: 23 days ago
JSON representation
🍂 A Flutter plugin for loading content asynchronously with Dart stream and RxDart. RxDart loader bloc. Reactive loader bloc. Simple reactive state management container - https://pub.dev/packages/stream_loader
- Host: GitHub
- URL: https://github.com/hoc081098/stream_loader
- Owner: hoc081098
- License: mit
- Created: 2020-01-12T07:15:52.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2024-09-17T23:02:18.000Z (8 months ago)
- Last Synced: 2024-09-18T03:29:56.684Z (8 months ago)
- Topics: bloc-architecture, bloc-pattern, bloc-pattern-rxdart, bloc-rxdart, flutter-bloc, flutter-bloc-pattern, flutter-bloc-pattern-rxdart, flutter-bloc-patterns, flutter-bloc-rxdart, flutter-bloc-sample, flutter-reactive, flutter-rx, flutter-rxbus, flutter-rxdart, flutter-stream, rxdart, rxdart-flutter, stream-loader
- Language: Dart
- Homepage: https://pub.dev/packages/stream_loader
- Size: 323 KB
- Stars: 3
- Watchers: 1
- Forks: 2
- Open Issues: 16
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# stream_loader 
- A `Flutter` plugin for loading content asynchronously with `Dart Stream` and `RxDart`.
- `RxDart` loader bloc.
- Reactive loader bloc.
- Simple reactive state management container.## Author: [Petrus Nguyễn Thái Học](https://github.com/hoc081098)
[](https://github.com/hoc081098/stream_loader/actions/workflows/dart.yml)
[](https://github.com/hoc081098/stream_loader/actions/workflows/build-example.yml)
[](https://pub.dartlang.org/packages/stream_loader)
[](https://travis-ci.org/hoc081098/stream_loader)
[](https://codecov.io/gh/hoc081098/stream_loader)
[](https://opensource.org/licenses/MIT)## Getting Started
In your flutter project, add the dependency to your `pubspec.yaml`
```yaml
dependencies:
...
stream_loader:
```## Examples
- [stream_loader/example](https://github.com/hoc081098/stream_loader/tree/master/example)
- [stream_loader_demo](https://github.com/hoc081098/stream_loader_demo)## Usage
![]()
#### 1. Model and api
```dart
abstract class Comment implements Built { ... }class Api {
Stream> getComments() { ... }
Stream getCommentBy({@required int id}) { ... }
}
final api = Api();
```#### 2. Create LoaderWidget load comments from api
```dart
import 'package:stream_loader/stream_loader.dart';LoaderWidget>(
blocProvider: () => LoaderBloc(
loaderFunction: api.getComments,
refresherFunction: api.getComments,
initialContent: [].build(),
logger: print,
),
messageHandler: (context, message, bloc) {
message.fold(
onFetchFailure: (error, stackTrace) => context.snackBar('Fetch error'),
onFetchSuccess: (_) {},
onRefreshSuccess: (data) => context.snackBar('Refresh success'),
onRefreshFailure: (error, stackTrace) => context.snackBar('Refresh error'),
);
},
builder: (context, state, bloc) {
if (state.error != null) {
return ErrorWidget(error: state.error);
}
if (state.isLoading) {
return LoadingWidget();
}
return RefreshIndicator(
onRefresh: bloc.refresh,
child: CommentsListWidget(comments: state.content),
);
}
);
```#### 3. Create LoaderWidget load comment detail from api
```dart
import 'package:stream_loader/stream_loader.dart';final Comment comment;
final loadDetail = () => api.getCommentBy(id: comment.id);LoaderWidget(
blocProvider: () => LoaderBloc(
loaderFunction: loadDetail,
refresherFunction: loadDetail,
initialContent: comment,
logger: print,
),
messageHandler: (context, message, bloc) {
message.fold(
onFetchFailure: (_, __) {},
onFetchSuccess: (_) {},
onRefreshFailure: (_, __) {},
onRefreshSuccess: (_) => context.snackBar('Refresh success'),
);
},
builder: (context, state, bloc) {
return RefreshIndicator(
onRefresh: bloc.refresh,
child: CommentDetailWidget(comment: state.content),
);
},
);
```#### Note: Can use `LoaderBloc` without `LoaderWidget` easily
```dartclass _CommentsState extends State {
LoaderBloc> bloc;@override
void didChangeDependencies() {
super.didChangeDependencies();bloc ??= LoaderBloc(
loaderFunction: api.getComments,
refresherFunction: api.getComments,
initialContent: [].build(),
logger: print,
)..fetch();
}@override
void dispose() {
bloc.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return StreamBuilder>>(
stream: bloc.state$,
initialData: bloc.state$.value, // <- required because bloc.state$ does not replay the latest value
builder: (context, snapshot) {
final state = snapshot.data;
if (state.error != null) {
return ErrorWidget(error: state.error);
}
if (state.isLoading) {
return LoadingWidget();
}
return RefreshIndicator(
onRefresh: bloc.refresh,
child: CommentsListWidget(comments: state.content),
);
}
);
}
}
```### Change _flatten behavior_ of `loaderFunction` and `refresherFunction`.
- Default behavior of `loaderFunction` is `FlattenStrategy.latest` (uses `switchMap`).
- Default behavior of `refreshFlatMapPolicy` is `FlattenStrategy.first`, (uses `exhaustMap`).
- To change them, passing your value to `LoaderBloc` constructor```dart
LoaderBloc(
...,
loaderFlattenStrategy: FlattenStrategy.concat, // asyncExpand
refreshFlattenStrategy: FlattenStrategy.latest, // switchMap
);
```## License
MIT License
Copyright (c) 2020-2022 Petrus Nguyễn Thái Học