---
title: Computed
description: Learn how to use Computed Signals
---

# Computed

A computed signal is a signal that depends on other signals.
To create a computed signal, you have to use the `Computed` class.

A `Computed` automatically subscribes to any signal provided and reruns when any of them change.

```dart
final name = Signal('John');
final lastName = Signal('Doe');
final fullName = Computed(() => '${name.value} ${lastName.value}');
print(fullName()); // prints "John Doe"

// Update the name
name.set('Jane');
print(fullName()); // prints "Jane Doe"
```

You may want to subscribe only to a sub-field of a `Signal` value.
```dart
// sample User class
class User {
  const User({
    required this.name,
    required this.age,
  });

  final String name;
  final int age;

  User copyWith({
    String? name,
    int? age,
  }) {
    return User(
      name: name ?? this.name,
      age: age ?? this.age,
    );
  }
}

// create a user signal
final user = Signal(const User(name: "name", age: 20));

// create a derived signal just for the age
final age = Computed(() => user().age);

// adding an effect to print the age
Effect(() {
  print('age changed from ${age.previousValue} into ${age.value}');
});

// just update the name, the effect above doesn't run because the age has not changed
user.updateValue((value) => value.copyWith(name: 'new-name'));

// just update the age, the effect above prints
user.updateValue((value) => value.copyWith(age: 21));
```

A derived signal is not of type `Signal` but is a `ReadSignal`.
The difference with a normal `Signal` is that a `ReadSignal` doesn't have a value setter, in other words it's a __read-only__ signal.

You can also use derived signals in other ways, like here:
```dart
final counter = Signal(0);
final doubleCounter = Computed(() => counter() * 2);
```

Every time the `counter` signal changes, the doubleCounter updates with the new doubled `counter` value.

You can also transform the value type into a `bool`:
```dart
final counter = Signal(0); // type: int
final isGreaterThan5 = Computed(() => counter() > 5); // type: bool
```

`isGreaterThan5` will update only when the `counter` value becomes lower/greater than `5`.
- If the `counter` value is `0`, `isGreaterThan5` is equal to `false`.
- If you update the value to `1`, `isGreaterThan5` doesn't emit a new value, but still contains `false`.
- If you update the value to `6`, `isGreaterThan5` emits a new `true` value.
