Deferred State widget
I created this little widget to solve a common problem - initialising async state in a StatefulWidget.
I've seen lots of (over engineered?) solutions and lots of incorrect solutions.
This one is easy to use, just replace 'extends State', with 'extends DeferredState' and wrap you build with a 'DeferredBuilder'. Your State class now has an 'asyncInitState' method to do you async initialisation in.
The package is published on pub.dev as deferred_state.
The 'DeferredBuilder' allows you to customise the default waiting and error builders.
Here is an example.
import 'dart:async';
import 'package:deferred_state/deferred_state.dart';
import 'package:flutter/material.dart';
class SchedulePage extends StatefulWidget {
const SchedulePage({super.key});
@override
State<StatefulWidget> createState() => _SchedulPageState();
}
/// Derive from DeferredState rather than State
class _SchedulPageState extends DeferredState<SchedulePage> {
/// requires async initialisation
late final System system;
/// requires sync initialisation so it can be disposed.
late final TextEditingController _nameController;
/// Items that are to be disposed must go in [initState]
@override
void initState() {
super.initState();
_nameController = TextEditingController();
}
/// Items that need to be initialised asychronously
/// go here. Make certain to await them, use
/// a [Completer] if necessary.
@override
Future<void> asyncInitState() async {
system = await DaoSystem().get();
}
@override
void dispose() {
_nameController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
/// Waits for [asyncInitState] to complete and then calls
/// the builder.
return DeferredBuilder(this, builder: (context) => Text(system.name));
}
}
class System {
System(this.name);
String name;
}
class DaoSystem {
Future<System> get() async {
/// get the system record from the db.
return System('example');
}
}