Project Name | Stars | Downloads | Repos Using This | Packages Using This | Most Recent Commit | Total Releases | Latest Release | Open Issues | License | Language |
---|---|---|---|---|---|---|---|---|---|---|
Wishtack Steroids | 89 | 2 | 1 | a year ago | 10 | December 16, 2019 | 36 | mit | TypeScript | |
Frontend on Steroids: Reactive Component Loader, RxJS Scavenger... | ||||||||||
Rxjs React | 51 | 5 years ago | 3 | June 06, 2018 | mit | JavaScript | ||||
make your react-component become reactive with rxjs | ||||||||||
Rxpagingloading | 41 | 2 years ago | 2 | March 05, 2021 | mit | Kotlin | ||||
Easy handling of the Paging or Loading screens states | ||||||||||
Tracker Component | 38 | 170 | 3 | 7 years ago | 32 | May 22, 2016 | 8 | mit | JavaScript | |
Easy reactive React Components with Meteor and Tracker | ||||||||||
Hoard | 7 | 4 years ago | 2 | apache-2.0 | Kotlin | |||||
Kotlin library for reactive data loading | ||||||||||
Vue Apollo | 6 | 7 years ago | mit | JavaScript | ||||||
Unofficial Vue2 integration for Apollo | ||||||||||
Reactive Yui | 5 | 9 years ago | 1 | JavaScript | ||||||
Reactive module for yui | ||||||||||
Rxuil | 4 | 6 years ago | mit | Java | ||||||
A reactive layer on top of universal image loader (easy and hassle-free) using RxJava 2 | ||||||||||
Stream_loader | 3 | 7 months ago | 4 | mit | Dart | |||||
🍂 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 | ||||||||||
Ngx Reactive Loading | 2 | a year ago | mit | TypeScript | ||||||
Reactive loading state management for Angular applications |
Flutter
plugin for loading content asynchronously with Dart Stream
and RxDart
.RxDart
loader bloc.In your flutter project, add the dependency to your pubspec.yaml
dependencies:
...
stream_loader: <latest_version>
abstract class Comment implements Built<Comment, CommentBuilder> { ... }
class Api {
Stream<BuiltList<Comment>> getComments() { ... }
Stream<Comment> getCommentBy({@required int id}) { ... }
}
final api = Api();
import 'package:stream_loader/stream_loader.dart';
LoaderWidget<BuiltList<Comment>>(
blocProvider: () => LoaderBloc(
loaderFunction: api.getComments,
refresherFunction: api.getComments,
initialContent: <Comment>[].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),
);
}
);
import 'package:stream_loader/stream_loader.dart';
final Comment comment;
final loadDetail = () => api.getCommentBy(id: comment.id);
LoaderWidget<Comment>(
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),
);
},
);
LoaderBloc
without LoaderWidget
easily
class _CommentsState extends State<Comments> {
LoaderBloc<BuiltList<Comment>> bloc;
@override
void didChangeDependencies() {
super.didChangeDependencies();
bloc ??= LoaderBloc(
loaderFunction: api.getComments,
refresherFunction: api.getComments,
initialContent: <Comment>[].build(),
logger: print,
)..fetch();
}
@override
void dispose() {
bloc.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return StreamBuilder<LoaderState<BuiltList<Comment>>>(
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),
);
}
);
}
}
loaderFunction
and refresherFunction
.loaderFunction
is FlattenStrategy.latest
(uses switchMap
).refreshFlatMapPolicy
is FlattenStrategy.first
, (uses exhaustMap
).LoaderBloc
constructorLoaderBloc(
...,
loaderFlattenStrategy: FlattenStrategy.concat, // asyncExpand
refreshFlattenStrategy: FlattenStrategy.latest, // switchMap
);
MIT License
Copyright (c) 2020-2022 Petrus Nguyễn Thái Học