Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/nivisi/ensure_initialized
⏲ Await until an object initialises before using it.
https://github.com/nivisi/ensure_initialized
await await-async dart dart-package dartlang ensure flutter flutter-package future initialization
Last synced: about 1 month ago
JSON representation
⏲ Await until an object initialises before using it.
- Host: GitHub
- URL: https://github.com/nivisi/ensure_initialized
- Owner: nivisi
- License: mit
- Created: 2021-08-02T11:40:08.000Z (over 3 years ago)
- Default Branch: develop
- Last Pushed: 2022-11-18T12:15:50.000Z (about 2 years ago)
- Last Synced: 2024-04-28T07:28:14.040Z (8 months ago)
- Topics: await, await-async, dart, dart-package, dartlang, ensure, flutter, flutter-package, future, initialization
- Language: Dart
- Homepage: https://pub.dev/packages/ensure_initialized
- Size: 57.6 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# ensure_initialized [![pub version][pub-version-img]][pub-version-url]
[![⚙️ CI][ci-badge-url]][ci-url] [![CodeFactor][code-factor--badge-url]][code-factor-app-url] [![codecov][codecov-badge-url]][codecov-url]
Sometimes objects may perform long initialization or preparation before they can be used. This package allows to await for initialization and ensure that an object is ready to use.
## Usage
Add the `EnsureInitializedMixin` mixin to a class:
```dart
class YourObject with EnsureInitializedMixin {
/* Body */
}
```Now you can await for your object initialization:
```dart
final object = YourObject();await object.ensureInitialized;
object.doSomethingAfterItIsReady();
```If your initialization has some output value, you can use `EnsureInitializedResultMixin`:
```dart
class YourObjectWithResult with EnsureInitializedResultMixin {
/* Body */
}final objectWithResult = YourObjectWithResult();
final result = await objectWithResult.ensureInitialized;
print(result);
```You can also check whether your object was already initialized by reading the `isInitialized` property:
```dart
final object = YourObject();print(object.isInitialized); // false
await object.init(); // object method that calls `initializedSuccessfully` under the hood
print(object.isInitialized); // true
```### Successful Initialization
`ensureInitialized` will be released after you call either `initializedSuccessfully`. Do it in your heavy initialization method:
```dart
```dart
class YourObject with EnsureInitializedMixin {
Future init() async {
await Future.delayed(const Duration(seconds: 3));initializedSuccessfully();
}
}
```If you use `EnsureInitializedResultMixin`, you must pass a value of type `T` to the call:
```dart
initializedSuccessfully(5);
```This value will be returned by the `ensureInitialized`:
```dart
final result = await objectWithResult.ensureInitialized;
print(result); // prints 5
```### Initialization Failure
To mark that the object has failed to initialize, call `initializedWithError`. It can take a message, an exception and a stacktrace.
Note: you can either use a message or an exception. You'll get an assertion error in debug otherwise.
```dart
Future init() async {
try {
await Future.delayed(const Duration(seconds: 3));
initializedSuccessfully();
} on Exception catch (e, s) {
initializedWithError(error: e, stackTrace: s);
// Or use message: initializedWithError(message: e.toString(), stackTrace: s);
}
}
```So `ensureInitialized` may throw the specified exception. It could be used as following:
```dart
try {
await object.ensureInitialized;
/* Do the happy path */
} on Exception catch (e ,s) {
/* Log it and do the unhappy path */
}
```Note that calling `initializedWithError` also turns `isInitialized` to true.
### Streams
There are `whenInitialized` and `whenUninitialized` streams that will raise an event when the object is initialized and uninitialized (later on about the latter):
```dart
object.whenInitialized.listen((_) {
print('My object was initialized!');
});
```It can also be used with the result mixin. Then the event will be the result of initialization:
```dart
objectWithResult.whenInitialized.listen((result) {
print('My object was initialized with $result!');
});
````whenInitialized` is fired any time `initializedSuccessfully` or `initializedWithError` are called. If the object was initialized with an error, this error will be added to the stream as well.
`whenUninitialized` is fired any time the object is marked as uninitialized.
### Reinitialization
Sometimes it is needed to reinit an object. For instance, some service relies on the user service, that relies on what user is currently signed in. You can call `markAsUninitialized` to point that the object is not ready to be used again.
```dart
class UserService with EnsureInitializedMixin {
Future signIn(credentials) async {
/* Do sign in */
initializedSuccessfully();
}
Future signOut() async {
/* Do sign out */
markAsUninitialized();
}
}
```Now, if you call `signOut`, the object will return to its initial state: `isInitialized` will be false and `ensureInitialized` will again be awaitable. It will also fire the `whenUninitialized` event.
So now we can get notified about this in another service:
```dart
class ServiceThatReliesOnUserService with EnsureInitializedMixin {
final UserService userService;
late final StreamSubscription _onInitializedSubscription;
late final StreamSubscription _onUninitializedSubscription;
ServiceThatReliesOnUserService(this.userService) {
_init();
}
void _init() {
_onInitializedSubscription = userService.whenInitialized.listen(_whenUserServiceInitialized);
_onUninitializedSubscription = userService.whenUninitialized.listen(_whenUserServiceUninitialized);
}
void _whenUserServiceInitialized(_) {
/* Do something with userService */
initializedSuccessfully();
}
void _whenUserServiceUninitialized(_) {
markAsUninitialized();
}
void dispose() {
_onInitializedSubscription.cancel();
_onUninitializedSubscription.cancel();
}
}
```We can build chains with objects that rely on each other. Don'get overwhelmed, though!
Alternatively, you can use a `reinitialize` method that takes a future as a parameter. The object will be marked as uninitialized before the future starts and will be marked as initialized after it completes.
```dart
Future reinitMe() {
return reinitialize(() => Future.delayed(const Duration(seconds: 3)));
}
```Note: if any exception occur, `reinitialize` will rethrow it. It also takes a flag `callInitializedWithErrorOnException` that indicates whether to call `initializedWithError` on exception.
[pub-version-img]: https://img.shields.io/badge/pub-v0.1.0-0175c2?logo=dart
[pub-version-url]: https://pub.dev/packages/ensure_initialized[code-factor--badge-url]: https://www.codefactor.io/repository/github/nivisi/ensure_initialized/badge
[code-factor-app-url]: https://www.codefactor.io/repository/github/nivisi/ensure_initialized[ci-badge-url]: https://github.com/nivisi/ensure_initialized/actions/workflows/ci.yml/badge.svg
[ci-url]: https://github.com/nivisi/ensure_initialized/actions/workflows/ci.yml[codecov-badge-url]: https://codecov.io/gh/nivisi/ensure_initialized/branch/develop/graph/badge.svg?token=80NZYCFQH3
[codecov-url]: https://codecov.io/gh/nivisi/ensure_initialized