import 'package:fl_query/models/query_job.dart'; import 'package:fl_query/query.dart'; import 'package:fl_query/query_bowl.dart'; import 'package:fl_query/utils.dart'; import 'package:flutter/widgets.dart'; class QueryBuilder extends StatefulWidget { final Function(BuildContext, Query) builder; final QueryJob job; final Outside externalData; /// Called when the query returns new data, on query /// refetch or query gets expired final QueryListener? onData; /// Called when the query returns error final QueryListener? onError; const QueryBuilder({ required this.job, required this.externalData, required this.builder, this.onData, this.onError, Key? key, }) : super(key: key); @override State> createState() => _QueryBuilderState(); } class _QueryBuilderState extends State> { late QueryBowl queryBowl; late final ValueKey uKey; late Query query; @override void initState() { super.initState(); uKey = ValueKey(uuid.v4()); query = Query.fromOptions( widget.job, externalData: widget.externalData, ); WidgetsBinding.instance.addPostFrameCallback((_) async { query = QueryBowl.of(context).addQuery( query, key: uKey, onData: widget.onData, onError: widget.onError, ); await query.fetch(); }); } @override void didUpdateWidget(covariant oldWidget) { if (oldWidget.externalData != widget.externalData) { QueryBowl.of(context).fetchQuery( widget.job, externalData: widget.externalData, onData: widget.onData, onError: widget.onError, key: uKey, ); } else { if (oldWidget.onData != widget.onData && oldWidget.onData != null) { query.onDataListeners.remove(oldWidget.onData); if (widget.onData != null) query.onDataListeners.add(widget.onData!); } if (oldWidget.onError != widget.onError && oldWidget.onError != null) { query.onErrorListeners.remove(oldWidget.onError); if (widget.onError != null) query.onErrorListeners.add(widget.onError!); } } super.didUpdateWidget(oldWidget); } @override void dispose() { query.unmount(uKey); if (widget.onData != null) query.onDataListeners.remove(widget.onData); if (widget.onError != null) query.onErrorListeners.remove(widget.onError); super.dispose(); } @override Widget build(BuildContext context) { queryBowl = QueryBowl.of(context); final latestQuery = queryBowl.getQuery(query.queryKey) ?? query; return widget.builder(context, latestQuery); } }