rx_shared_preferences

Creator: coderz1093

Last updated:

Add to Cart

Description:

rx shared preferences

rx_shared_preferences #
Author: Petrus Nguyễn Thái Học #














Shared preference with rxdart Stream observation.
Reactive shared preferences for Flutter.
Reactive stream wrapper around SharedPreferences.
This package provides reactive shared preferences interaction with very little code. It is designed specifically to be used with Flutter and Dart.

Buy me a coffee #
Liked some of my work? Buy me a coffee (or more likely a beer)

Note #
Since version 1.3.4, this package is an extension of rx_storage package.
More details about the returned Stream #


It's a single-subscription Stream (i.e. it can only be listened once).


Stream will emit the value (nullable) or a TypeError as its first event when it is listened to.


It will automatically emit the new value when the value associated with key was changed successfully
(it will also emit null when value associated with key was removed or set to null).


When value read from Storage has a type other than expected type:

If value is null, the Stream will emit null (this occurred because null can be cast to any nullable type).
Otherwise, the Stream will emit a TypeError.



Can emit two consecutive data events that are equal.
You should use Rx operator like distinct
(more commonly known as distinctUntilChanged in other Rx implementations)
to create a Stream where data events are skipped if they are equal to the previous data event.


Key changed |----------K1---K2------K1----K1-----K2---------> time
|
Value stream |-----@----@------------@-----@-----------------> time
| ^
| |
| Listen(key=K1)
|
| @: nullable value or TypeError
copied to clipboard



Getting Started #
In your flutter project, add the dependency to your pubspec.yaml
dependencies:
[...]
rx_shared_preferences: <latest_version>
copied to clipboard
Usage #
1. Import and instantiate #

Import rx_shared_preferences.

import 'package:rx_shared_preferences/rx_shared_preferences.dart';
copied to clipboard

Wrap your SharedPreferences in a RxSharedPreferences.

// via constructor.
final rxPrefs = RxSharedPreferences(await SharedPreferences.getInstance()); // use await
final rxPrefs = RxSharedPreferences(SharedPreferences.getInstance()); // await is optional
final rxPrefs = RxSharedPreferences.getInstance(); // default singleton instance

// via extension.
final rxPrefs = (await SharedPreferences.getInstance()).rx; // await is required
copied to clipboard

NOTE: When using RxSharedPreferences.getInstance() and extension (await SharedPreferences.getInstance()).rx,
to config the logger, you can use RxSharedPreferencesConfigs.logger setter.

2. Add a logger (optional) #
You can pass a logger to the optional parameter of RxSharedPreferences constructor.
The logger will log messages about operations (such as read, write, ...) and stream events.
This package provides two RxSharedPreferencesLoggers:

RxSharedPreferencesDefaultLogger.
RxSharedPreferencesEmptyLogger.

final rxPrefs = RxSharedPreferences(
SharedPreferences.getInstance(),
kReleaseMode ? null : RxSharedPreferencesDefaultLogger(),
// disable logging when running in release mode.
);
copied to clipboard

NOTE: To disable logging when running in release mode, you can pass null or const RxSharedPreferencesEmptyLogger()
to RxSharedPreferences constructor, or use RxSharedPreferencesConfigs.logger setter.


NOTE: To prevent printing ↓ Disposed successfully → DisposeBag#....
import 'package:disposebag/disposebag.dart' show DisposeBagConfigs;
void main() {
DisposeBagConfigs.logger = null;
}
copied to clipboard

3. Select stream and observe #

Then, just listen Streams, transform Streams through operators such as map, flatMap, etc...
If you need to listen to the Stream many times, you can use broadcast operators such as share, shareValue, publish, publishValue, etc...

// Listen
rxPrefs.getStringListStream('KEY_LIST').listen(print); // [*]

// Broadcast stream
rxPrefs.getStringListStream('KEY_LIST').share();
rxPrefs.getStringListStream('KEY_LIST').shareValue();
rxPrefs.getStringListStream('KEY_LIST').asBroadcastStream();

// Transform stream
rxPrefs.getIntStream('KEY_INT')
.map((i) => /* Do something cool */)
.where((i) => /* Filtering */)
...

// must **use same rxPrefs** instance when set value and select stream
await rxPrefs.setStringList('KEY_LIST', ['Cool']); // [*] will print ['Cool']
copied to clipboard


In the previous example, we re-used the RxSharedPreferences object rxPrefs for all operations.
All operations must go through this object in order to correctly notify subscribers.
Basically, you must use the same RxSharedPreferences instance when set value and select stream.


In a Flutter app, you can:


Create a global RxSharedPreferences instance.


Use the default singleton instance via RxSharedPreferences.getInstance().


Use InheritedWidget/Provider to provide a RxSharedPreferences instance (create it in main function) for all widgets (recommended).
See example/main.




// An example for wrong usage.

rxPrefs1.getStringListStream('KEY_LIST').listen(print); // [*]

rxPrefs2.setStringList('KEY_LIST', ['Cool']); // [*] will not print anything,
// because rxPrefs1 and rxPrefs2 are different instances.
copied to clipboard
4. Stream APIs and RxStorage APIs #

All Streams APIs (via extension methods).

Stream<Object?> getObjectStream(String key, [Decoder<Object?>? decoder]);
Stream<bool?> getBoolStream(String key);
Stream<double?> getDoubleStream(String key);
Stream<int?> getIntStream(String key);
Stream<String?> getStringStream(String key);
Stream<List<String>?> getStringListStream(String key);
Stream<Set<String>> getKeysStream();

Future<void> updateBool(String key, Transformer<bool?> transformer);
Future<void> updateDouble(String key, Transformer<double?> transformer);
Future<void> updateInt(String key, Transformer<int?> transformer);
Future<void> updateString(String key, Transformer<String?> transformer);
Future<void> updateStringList(String key, Transformer<List<String>?> transformer);
copied to clipboard

All methods from RxStorage
(because RxSharedPreferences implements RxStorage).

Future<void> update<T extends Object>(String key, Decoder<T?> decoder, Transformer<T?> transformer, Encoder<T?> encoder);
Stream<T?> observe<T extends Object>(String key, Decoder<T?> decoder);
Stream<Map<String, Object?>> observeAll();
Future<void> dispose();
copied to clipboard
5. Get and set methods likes SharedPreferences #

RxSharedPreferences is like to SharedPreferences, it provides read, write functions (via extension methods).

Future<Object?> getObject(String key, [Decoder<Object?>? decoder]);
Future<bool?> getBool(String key);
Future<double?> getDouble(String key);
Future<int?> getInt(String key);
Future<Set<String>> getKeys();
Future<String?> getString(String key);
Future<List<String>?> getStringList(String key);

Future<Map<String, Object?>> reload();
Future<void> setBool(String key, bool? value);
Future<void> setDouble(String key, double? value);
Future<void> setInt(String key, int? value);
Future<void> setString(String key, String? value);
Future<void> setStringList(String key, List<String>? value);
copied to clipboard

All methods from Storage
(because RxSharedPreferences implements Storage).

Future<bool> containsKey(String key);
Future<T?> read<T extends Object>(String key, Decoder<T?> decoder);
Future<Map<String, Object?>> readAll();
Future<void> clear();
Future<void> remove(String key);
Future<void> write<T extends Object>(String key, T? value, Encoder<T?> encoder);
copied to clipboard
6. Dispose #
You can dispose the RxSharedPreferences when it is no longer needed.
Just call rxPrefs.dispose().
Usually, you call this method on dispose method of a Flutter State.
Example demo #



Simple authentication app with BLoC rxdart pattern
Build ListView from Stream using RxSharedPreferences
Change theme and locale (language) runtime










Features and bugs #
Please file feature requests and bugs at the issue tracker.
License #
MIT License

Copyright (c) 2019-2024 Petrus Nguyễn Thái Học
copied to clipboard
Contributors ✨ #
Thanks goes to these wonderful people (emoji key):





Petrus Nguyễn Thái Học💻 📖 🚧





This project follows the all-contributors specification. Contributions of any kind welcome!

License

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Customer Reviews

There are no reviews.