Skip to main content

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

  1. Observable Streams: RxDart provides an abstraction called Observable that 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);
  2. 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, and merge enable 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 map operator doubles each value emitted by the observable stream.

  3. Subscription Management: RxDart provides ways to manage subscriptions to observables. The StreamSubscription class 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.

  4. Error Handling: RxDart provides operators to handle errors emitted by observables. Operators like onErrorResumeNext and retry allow 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 onErrorResumeNext operator catches the error emitted by the observable and replaces it with a new observable that emits a single value of 42.

  5. Concurrency Control: RxDart provides operators for controlling the concurrency of observables. Operators like debounce, throttle, and delay allow 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 observable stream by 1 second.

Examples

  1. 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.

  2. 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 clicked

    This 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.

  3. 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: 4

    This example creates an observable from a list of numbers and filters out the odd numbers using the where operator. 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