Skip to content

MergedObservable

Observables that combine multiple values using the merge operator (+).

FynX MergedObservable - Combined Reactive Values

This module provides the MergedObservable class, which combines multiple individual observables into a single reactive computed observable. This enables treating related observables as a cohesive group that updates atomically when any component changes.

Merged observables are read-only computed observables that derive their value from their source observables. They are useful for:

  • Coordinated Updates: When multiple values need to change together
  • Computed Relationships: When derived values depend on multiple inputs
  • Tuple Operations: When you need to pass multiple reactive values as a unit
  • State Composition: Building complex state from simpler reactive components

The merge operation is created using the + operator between observables:

from fynx import observable

width = observable(10)
height = observable(20)
dimensions = width + height  # Creates MergedObservable
print(dimensions.value)  # (10, 20)

width.set(15)
print(dimensions.value)  # (15, 20)

# Merged observables are read-only
dimensions.set((5, 5))  # Raises ValueError: Computed observables are read-only

MergedObservable

MergedObservable(*observables)

A computed observable that combines multiple observables into a single reactive tuple.

MergedObservable creates a read-only computed observable whose value is a tuple containing the current values of all source observables. When any source observable changes, the merged observable automatically recalculates its tuple value and notifies all subscribers.

As a computed observable, MergedObservable is read-only and cannot be set directly. Its value is always derived from its source observables, ensuring consistency.

This enables treating multiple related reactive values as a single atomic unit, which is particularly useful for:

  • Functions that need multiple related parameters
  • Computed values that depend on several inputs
  • Coordinated state updates across multiple variables
  • Maintaining referential consistency between related values
Example
from fynx import observable

# Individual observables
x = observable(10)
y = observable(20)

# Merge them into a single reactive unit
point = x + y
print(point.value)  # (10, 20)

# Computed values can work with the tuple
distance_from_origin = point.then(
    lambda px, py: (px**2 + py**2)**0.5
)
print(distance_from_origin.value)  # 22.360679774997898

# Changes to either coordinate update everything
x.set(15)
print(point.value)                  # (15, 20)
print(distance_from_origin.value)   # 25.0
Note

The merged observable's value is always a tuple, even when merging just two observables. This provides a consistent interface for computed functions.

See Also

ComputedObservable: Base computed observable class

operator: For creating derived values from merged observables

Create a merged observable from multiple source observables.

Parameters:

Name Type Description Default
*observables Observable

Variable number of Observable instances to combine. At least one observable must be provided.

()

Raises:

Type Description
ValueError

If no observables are provided

value

value

Get the current tuple value, using cache when possible.

Returns the current values of all source observables as a tuple. Uses caching to avoid recomputing the tuple on every access.

Returns:

Type Description

A tuple containing the current values of all source observables,

in the order they were provided to the constructor.

Example
x = Observable("x", 10)
y = Observable("y", 20)
merged = x + y

print(merged.value)  # (10, 20)
x.set(15)
print(merged.value)  # (15, 20) - cache invalidated and recomputed

__add__

__add__(other)

Chain merging with another observable using the + operator.

Enables fluent syntax for building up merged observables incrementally. Each + operation creates a new MergedObservable containing all previous observables plus the new one.

Parameters:

Name Type Description Default
other Observable

Another Observable to merge with this merged observable

required

Returns:

Type Description
MergedObservable

A new MergedObservable containing all source observables from this

MergedObservable

merged observable plus the additional observable.

__enter__

__enter__()

Context manager entry for reactive blocks.

Enables experimental syntax for defining reactive blocks that execute whenever any of the merged observables change.

Returns:

Type Description

A context object that can be called with a function to create reactive behavior.

Example
# Experimental context manager syntax
with merged_obs as ctx:
    ctx(lambda x, y: print(f"Values changed: {x}, {y}"))
Note

This is an experimental feature. The more common approach is to use subscribe() or the @reactive decorator.

__exit__

__exit__(exc_type, exc_val, exc_tb)

Context manager exit.

Currently does nothing, but allows the context manager to work properly.

subscribe

subscribe(func)

Subscribe a function to react to changes in any of the merged observables.

The subscribed function will be called whenever any source observable changes. This provides a way to react to coordinated changes across multiple observables.

Parameters:

Name Type Description Default
func Callable

A callable that will receive the current values of all merged observables as separate arguments, in the order they were merged. The function signature should match the number of merged observables.

required

Returns:

Type Description
MergedObservable[T]

This merged observable instance for method chaining.

Examples:

x = Observable("x", 1)
y = Observable("y", 2)
coords = x + y

def on_coords_change(x_val, y_val):
    print(f"Coordinates: ({x_val}, {y_val})")

coords.subscribe(on_coords_change)

x.set(10)  # Prints: "Coordinates: (10, 2)"
y.set(20)  # Prints: "Coordinates: (10, 20)"
Note

The function is called only when observables change. It is not called immediately upon subscription.

See Also

unsubscribe: Remove a subscription reactive: Decorator-based reactive functions

unsubscribe

unsubscribe(func)

Unsubscribe a function from this merged observable.

Removes the subscription for the specified function, preventing it from being called when the merged observable changes. This properly cleans up the reactive context and removes all observers.

Parameters:

Name Type Description Default
func Callable

The function that was previously subscribed to this merged observable. Must be the same function object that was passed to subscribe().

required

Examples:

def handler(x, y):
    print(f"Changed: {x}, {y}")

coords = x + y
coords.subscribe(handler)

# Later, unsubscribe
coords.unsubscribe(handler)  # No longer called when coords change
Note

This only removes subscriptions to this specific merged observable. If the same function is subscribed to other observables, those subscriptions remain active.

See Also

subscribe: Add a subscription