watch_it library

Classes

Disposable
If objects that are registered inside GetIt implements Disposable the onDispose method will be called whenever that Object is unregistered, resetted or its enclosing Scope is popped
GetIt
Very simple and easy to use service locator You register your object creation factory or an instance of an object with registerFactory, registerSingleton or registerLazySingleton And retrieve the desired object using get or call your locator as function as its a callable class Additionally GetIt offers asynchronous creation functions as well as functions to synchronize the async initialization of multiple Singletons
InitDependency
Data structure used to identify a dependency by type and instanceName
ShadowChangeHandlers
If an object implements the ShadowChangeHandler if will get notified if an Object with the same registration type and name is registered on a higher scope which will shadow it. It also will get notified if the shadowing object is removed from GetIt
WatchingStatefulWidget
WatchingWidget
WillSignalReady
If your singleton that you register wants to use the manually signalling of its ready state, it can implement this interface class instead of using the signalsReady parameter of the registration functions (you don't really have to implement much ;-) )

Properties

di GetIt
WatchIt exports the default instance of get_it as a global variable which lets you access it from anywhere in your app. To access any get_it registered object you only have to type di<MyType>() instead of GetIt.I<MyType>(). if you don't want to use a different instance of get_it you can pass it to the functions of this library as an optional parameter
final

Functions

allReady({void onReady(BuildContext context)?, void onError(BuildContext context, Object? error)?, Duration? timeout, bool callHandlerOnlyOnce = false}) bool
returns true if all registered async or dependent objects are ready and call onReady and onError handlers when the all-ready state is reached. You can force a timeout Exception if allReady hasn't returned true within timeout. It will trigger a rebuild if this state changes If no onError is passed in it will throw an exception if an error occurs while waiting for the all-ready state. callHandlerOnlyOnce determines if the onReady and onError handlers should be called only once or on every rebuild after the all-ready state has been reached.
allReadyHandler(void onReady(BuildContext context)?, {void onError(BuildContext context, Object? error)?, Duration? timeout, bool callHandlerOnlyOnce = false}) → void
registers a handler that is called when the all-ready state is reached it does not trigger a rebuild like allReady does. You can force a timeout Exception if allReady has completed within timeout which will call onError if no onError is passed in it will throw an exception if an error occurs while waiting for the all-ready state. callHandlerOnlyOnce determines if the onReady and onError handlers should be called only once or on every rebuild after the all-ready state has been reached.
callOnce(void init(BuildContext context), {void dispose()?}) → void
If you want to execute a function only on the first built (even in in a StatelessWidget), you can use the callOnce function anywhere in your build function. It has an optional dispose handler which will be called when the widget is disposed.
isReady<T extends Object>({void onReady(BuildContext context)?, void onError(BuildContext context, Object? error)?, Duration? timeout, String? instanceName}) bool
returns true if the registered async or dependent object defined by T and instanceName is ready and calls onReady onError handlers when the ready state is reached. You can force a timeout Exception if isReady hasn't returned true within timeout. It will trigger a rebuild if this state changes. if no onError is passed in it will throw an exception if an error occurs
onDispose(void dispose()) → void
To dispose anything when the widget is disposed you can use call onDispose anywhere in your build function.
pushScope({void init(GetIt getIt)?, void dispose()?, bool isFinal = false}) → void
Pushes a new GetIt-Scope. After pushing, it executes init where you can register objects that should only exist as long as this scope exists. Can be called inside the build method of a StatelessWidget. It ensures that it's only called once in the lifetime of a widget. isFinal allows only objects in init to be registered so that other components cannot accidentally register to this scope. When the widget is destroyed the scope also gets destroyed after dispose is executed. If you use this function and you have registered your objects with an async disposal function, that function won't be awaited. I would recommend doing pushing and popping from your business layer but sometimes this might come in handy.
rebuildOnScopeChanges() bool?
Will trigger a rebuild of the Widget if any new GetIt-Scope is pushed or popped. This function will return true if the change was a push otherwise false. If no change has happened then the return value will be null.
registerChangeNotifierHandler<T extends ChangeNotifier>({required void handler(BuildContext context, T newValue, void cancel()), T? target, bool executeImmediately = false, String? instanceName, GetIt? getIt}) → void
registerChangeNotifierHandler registers a handler function for a ChangeNotifier exactly once on the first build and unregisters it when the widget is destroyed. If you set executeImmediately to true the handler will be called immediately with the current value of the ChangeNotifier and not on the first change notification. All handler functions get passed in a cancel function that allows to kill the registration from inside the handler. If you want to register a handler to a ChangeNotifier that is not registered in get_it you can pass it as target. instanceName is the optional name of the instance if you registered it with a name in get_it.
registerFutureHandler<T extends Object, R>({Future<R> select(T)?, T? target, required void handler(BuildContext context, AsyncSnapshot<R?> newValue, void cancel()), R? initialValue, String? instanceName, bool callHandlerOnlyOnce = false, GetIt? getIt}) → void
registerFutureHandler registers a handler function for a Future exactly once on the first build and unregisters it when the widget is destroyed. This handler will only be called once when the Future completes. select allows you to register the handler to a member of the of the Object stored in GetIt. If you pass initialValue your passed handler will be executed immediately with that value. All handlers get passed in a cancel function that allows to kill the registration from inside the handler. If the Future has completed handler will be called every time until the handler calls cancel or the widget is destroyed
registerHandler<T extends Object, R>({ValueListenable<R> select(T)?, required void handler(BuildContext context, R newValue, void cancel()), T? target, bool executeImmediately = false, String? instanceName, GetIt? getIt}) → void
registerHandler registers a handler function for a ValueListenable exactly once on the first build and unregister it when the widget is destroyed. select allows you to register the handler to a member of the of the Object stored in GetIt. If you set executeImmediately to true the handler will be called immediately with the current value of the ValueListenable and not on the first change notification. All handler functions get passed in a cancel function that allows to kill the registration from inside the handler. If you want to register a handler to a Listenable that is not registered in get_it you can pass it as target. if you pass null as select, T or target has to be a Listenable or ValueListenable. instanceName is the optional name of the instance if you registered it with a name in get_it.
registerStreamHandler<T extends Object, R>({Stream<R> select(T)?, required void handler(BuildContext context, AsyncSnapshot<R?> newValue, void cancel()), R? initialValue, T? target, String? instanceName, GetIt? getIt}) → void
registerStreamHandler registers a handler function for a Stream exactly once on the first build and unregisters it when the widget is destroyed. select allows you to register the handler to a member of the of the Object stored in GetIt. If you pass initialValue your passed handler will be executed immediately with that value All handler functions get passed in a cancel function that allows to kill the registration from inside the handler. If you want to register a handler to a Stream that is not registered in get_it you can pass it as target. if you pass null as select, T or target has to be a Stream
throwIf(bool condition, Object error) → void
Two handy functions that help me to express my intention clearer and shorter to check for runtime errors
throwIfNot(bool condition, Object error) → void
watch<T extends Listenable>(T target) → T
The Watch functions:
watchFuture<T extends Object, R>(Future<R> select(T)?, {T? target, required R initialValue, String? instanceName, bool preserveState = true, GetIt? getIt}) AsyncSnapshot<R?>
watchFuture observes the Future returned by select and triggers a rebuild as soon as this Future completes. After that it returns an AsyncSnapshot with the received data from the Future When you call watchFuture a second time on the same Future it will return the last received data but not observe the Future a another time. To be able to use watchFuture inside a build function we have to pass initialValue so that it can return something before the Future has completed if select returns a different Future than on the last call, watchFuture will ignore the completion of the previous Future and observe the completion of the new Future. preserveState determines then if the new initial value should be the last value of the previous Future or again initialValue If you want to observe a Future that is not registered in get_it you can pass it as target. if you pass null as select, T or target has to be a Future
watchIt<T extends Listenable>({String? instanceName, GetIt? getIt}) → T
watchIt observes any Listenable registered in get_it and triggers a rebuild whenever it notifies a change. Its basically a shortcut for watch(di<T>()) instanceName is the optional name of the instance if you registered it with a name in get_it. getIt is the optional instance of get_it to use if you don't want to use the default one. 99% of the time you won't need this.
watchPropertyValue<T extends Listenable, R>(R selectProperty(T), {T? target, String? instanceName, GetIt? getIt}) → R
watchPropertyValue allows you to observe a property of a Listenable object and trigger a rebuild whenever the Listenable notifies a change and the value of the property changes and returns the current value of the property. You can achieve a similar result with watchIt<UserManager>().userName but that would trigger a rebuild whenever any property of the UserManager changes. final userName = watchPropertyValue<UserManager, String>((user) => user.userName); could be an example. Or even more expressive and concise: final userName = watchPropertyValue((UserManager user) => user.userName); which lets tha analyzer infer the type of T and R.
watchStream<T extends Object, R>(Stream<R> select(T)?, {T? target, R? initialValue, bool preserveState = true, String? instanceName, GetIt? getIt}) AsyncSnapshot<R>
watchStream subscribes to the Stream returned by select and returns an AsyncSnapshot with the latest received data from the Stream Whenever new data is received it triggers a rebuild. When you call watchStream a second time on the same Stream it will return the last received data but not subscribe another time. To be able to use watchStream inside a build function we have to pass initialValue so that it can return something before it has received the first data if select returns a different Stream than on the last call, watchStream will cancel the previous subscription and subscribe to the new stream. preserveState determines then if the new initial value should be the last value of the previous stream or again initialValue If you want to observe a Stream that is not registered in get_it you can pass it as target. if you pass null as select, T or target has to be a Stream
watchValue<T extends Object, R>(ValueListenable<R> selectProperty(T), {String? instanceName, GetIt? getIt}) → R
watchValue observes a ValueListenable property of an object registered in get_it and triggers a rebuild whenever it notifies a change and returns its current value. It's basically a shortcut for watchIt<T>().value As this is a common scenario it allows us a type safe concise way to do this. final userName = watchValue<UserManager, String>((user) => user.userName); is an example of how to use it. We can use the strength of generics to infer the type of the property and write it even more expressively like this: final userName = watchValue((UserManager user) => user.userName);

Typedefs

DisposingFunc<T> = FutureOr Function(T param)
Signature for disposing function because closures like (x){} have a return type of Null we don't use FutureOr<void>
FactoryFunc<T> = T Function()
Signature of the factory function used by non async factories
FactoryFuncAsync<T> = Future<T> Function()
Signature of the factory function used by async factories
FactoryFuncParam<T, P1, P2> = T Function(P1 param1, P2 param2)
For Factories that expect up to two parameters if you need only one use void for the one you don't use
FactoryFuncParamAsync<T, P1, P2> = Future<T> Function(P1 param1, P2 param2)
For async Factories that expect up to two parameters if you need only one use void for the one you don't use
ScopeDisposeFunc = FutureOr Function()
Signature for disposing function on scope level

Exceptions / Errors

WaitingTimeOutException