RxDart
RxDart: Introduction, History, Features, and Examples
Introduction
RxDart is a reactive programming library for Dart and Flutter that provides APIs for composing asynchronous and event-based programs using observable streams. Reactive programming is a programming paradigm that focuses on propagating changes and handling events in a declarative and asynchronous manner.
RxDart is built on top of the Dart Streams API and extends it with additional features and operators to make it easier to work with reactive streams. It provides a powerful and flexible way to handle asynchronous operations, manage state, and build complex event-driven applications.
History
RxDart is an implementation of the ReactiveX (Rx) programming model, which was originally introduced by Microsoft in their .NET framework. The ReactiveX model has since been adopted by various programming languages and platforms, including Dart and Flutter.
The RxDart library was first released in 2017 and has since become one of the most popular reactive programming libraries for Dart and Flutter development. It is actively maintained by a community of developers and has a growing ecosystem of plugins and extensions.
Features
Observable Streams: RxDart provides an abstraction called
Observablethat represents a stream of events or values over time. You can create observables from various data sources, such as streams, futures, or even from scratch using factory methods.final stream = Stream.fromIterable([1, 2, 3, 4]);
final observable = Observable(stream);Operators: RxDart provides a rich set of operators that allow you to transform, filter, and combine observables to create more complex streams. Operators like
map,filter,flatMap, andmergeenable you to manipulate the data emitted by observables.final observable = Observable.fromIterable([1, 2, 3]);
final doubled = observable.map((value) => value * 2);In this example, the
mapoperator doubles each value emitted by theobservablestream.Subscription Management: RxDart provides ways to manage subscriptions to observables. The
StreamSubscriptionclass allows you to listen to the events emitted by an observable and cancel the subscription when you no longer need it.final observable = Observable.periodic(Duration(seconds: 1), (value) => value);
final subscription = observable.listen(print);
// Cancel the subscription after 5 seconds
Future.delayed(Duration(seconds: 5), () => subscription.cancel());This code creates an observable that emits sequential numbers every second and prints them. After 5 seconds, the subscription is canceled.
Error Handling: RxDart provides operators to handle errors emitted by observables. Operators like
onErrorResumeNextandretryallow you to handle errors in a flexible and customizable way.final observable = Observable.error(Exception('Something went wrong'));
final handled = observable.onErrorResumeNext(Observable.just(42));In this example, the
onErrorResumeNextoperator catches the error emitted by theobservableand replaces it with a new observable that emits a single value of 42.Concurrency Control: RxDart provides operators for controlling the concurrency of observables. Operators like
debounce,throttle, anddelayallow you to control the rate at which events are emitted or processed.final observable = Observable.range(1, 10);
final delayed = observable.delay(Duration(seconds: 1));This code delays the emission of each value in the
observablestream by 1 second.
Examples
Simple Counter:
final counter = Observable.periodic(Duration(seconds: 1), (value) => value);
final subscription = counter.listen((value) => print('Count: $value'));
// Output: Count: 0, Count: 1, Count: 2, ...This example creates an observable that emits sequential numbers every second. The subscription listens to the events and prints the count.
Button Clicks:
final button = StreamController<void>();
final clicks = Observable(button.stream);
button.add(null); // Simulate a button click
final subscription = clicks.listen((_) => print('Button clicked'));
// Output: Button clickedThis example creates an observable from a stream controller that represents button clicks. The subscription listens to the clicks and prints a message each time the button is clicked.
Filtering Odd Numbers:
final numbers = Observable.fromIterable([1, 2, 3, 4, 5]);
final evens = numbers.where((value) => value % 2 == 0);
evens.listen((value) => print('Even number: $value'));
// Output: Even number: 2, Even number: 4This example creates an observable from a list of numbers and filters out the odd numbers using the
whereoperator. The subscription listens to the even numbers and prints them.
For more information and detailed documentation, you can visit the official RxDart website: https://pub.dev/packages/rxdart
RxDart is a powerful library that enables you to build reactive and event-driven applications in Dart and Flutter. Its rich set of features and operators make it easier to handle asynchronous operations, manage state, and compose complex streams of data. Whether you are building a simple counter or a complex UI with reactive components, RxDart provides the tools you need to write clean, efficient, and maintainable code.
title: RxDart Examples sidebar_label: RxDart sidebar_position: 9 slug: /rxdart
RxDart Examples.
RxDart: A Comprehensive Guide
Introduction
RxDart is a reactive programming library for Dart which is built on top of the Dart Streams API. It provides a powerful set of tools and operators for working with asynchronous data streams, enabling developers to easily handle complex asynchronous programming scenarios in a more declarative and functional way.
In this tutorial, we will explore the history, features, and examples of RxDart, and see how it can simplify and enhance your Dart programming experience.
History
RxDart is an extension of the popular Rx library, which originated in the world of functional reactive programming (FRP). FRP is a programming paradigm that facilitates the composition of asynchronous and event-driven programs. It was first introduced by Microsoft in the Reactive Extensions (Rx) framework for .NET.
RxDart brings the power of Rx to Dart developers, allowing them to leverage the reactive programming paradigm to handle complex asynchronous operations with ease.
Features
RxDart offers a rich set of features that make it a valuable tool for handling asynchronous programming tasks. Let's explore some of its key features:
1. Observables
Observables form the core of RxDart. An observable is a sequence of values that can be observed over time. It can emit multiple values asynchronously and can be subscribed to by multiple observers.
Here's an example that demonstrates how to create an observable using RxDart:
import 'package:rxdart/rxdart.dart';
void main() {
final observable = Observable.fromIterable([1, 2, 3, 4, 5]);
observable.listen((value) {
print(value);
});
}
Output:
1
2
3
4
5
In this example, we create an observable from an iterable and subscribe to it using the listen method. The observable emits each value from the iterable one by one, and the listener prints each value to the console.
2. Subjects
Subjects are a special type of observables that can act as both a source of values and a target for listening to values. They can be used to multicast values to multiple observers, making them useful for event bus and data sharing scenarios.
Here's an example that demonstrates how to use a subject in RxDart:
import 'package:rxdart/rxdart.dart';
void main() {
final subject = PublishSubject<int>();
subject.stream.listen((value) {
print('Observer 1: $value');
});
subject.stream.listen((value) {
print('Observer 2: $value');
});
subject.add(1);
subject.add(2);
subject.add(3);
subject.close();
}
Output:
Observer 1: 1
Observer 2: 1
Observer 1: 2
Observer 2: 2
Observer 1: 3
Observer 2: 3
In this example, we create a PublishSubject which is a type of subject that emits all the values to its subscribers. We add two listeners to the subject and then add values to it. Both listeners receive the emitted values.
3. Operators
RxDart provides a wide range of operators that allow you to transform, combine, and manipulate observables in various ways. These operators enable you to perform complex data processing tasks with minimal code.
Here's an example that demonstrates the use of the map and where operators:
import 'package:rxdart/rxdart.dart';
void main() {
final observable = Observable.fromIterable([1, 2, 3, 4, 5]);
observable
.map((value) => value * 2)
.where((value) => value > 5)
.listen((value) {
print(value);
});
}
Output:
6
8
10
In this example, we create an observable from an iterable and use the map operator to multiply each value by 2. Then, we use the where operator to filter out values that are not greater than 5. Finally, we listen to the resulting observable and print the filtered values.
Examples
Let's explore a few more examples to see how RxDart can be used in real-world scenarios:
Example 1: Debounce
Debouncing is a technique used to control the frequency of events emitted by an observable. It is often used in scenarios where you want to handle events only after a certain period of inactivity.
import 'package:rxdart/rxdart.dart';
void main() {
final buttonClicks = PublishSubject<void>();
buttonClicks
.debounceTime(Duration(seconds: 1))
.listen((_) {
print('Button clicked!');
});
buttonClicks.add(null);
buttonClicks.add(null);
buttonClicks.add(null);
// Wait for 2 seconds
Future.delayed(Duration(seconds: 2), () {
buttonClicks.add(null);
});
buttonClicks.close();
}
Output:
Button clicked!
In this example, we create a PublishSubject to represent button clicks. We use the debounceTime operator to debounce the button clicks and emit a value only after 1 second of inactivity. The listener prints "Button clicked!" whenever a debounced click event occurs.
Example 2: Combine Latest
The combineLatest operator allows you to combine the latest values from multiple observables into a single observable. This can be useful in scenarios where you need to synchronize and process data from multiple sources.
import 'package:rxdart/rxdart.dart';
void main() {
final name = BehaviorSubject<String>();
final age = BehaviorSubject<int>();
Observable.combineLatest2(name, age, (String name, int age) {
return 'Name: $name, Age: $age';
}).listen((value) {
print(value);
});
name.add('John');
age.add(25);
name.add('Jane');
age.add(30);
name.close();
age.close();
}
Output:
Name: John, Age: 25
Name: Jane, Age: 25
Name: Jane, Age: 30
In this example, we create two BehaviorSubject instances to represent a name and an age. We use the combineLatest2 operator to combine the latest values from both subjects and create a formatted string. The listener prints the combined values whenever either of the subjects emits a new value.
Conclusion
RxDart is a powerful reactive programming library for Dart that provides a wide range of tools and operators for working with asynchronous data streams. It simplifies complex asynchronous programming scenarios and enables developers to write cleaner and more maintainable code.
By leveraging observables, subjects, and operators, you can handle asynchronous operations with ease, and create more responsive and efficient Dart applications.
To learn more about RxDart, you can visit the official website: RxDart Official Site