Skip to content

Angular Signals: linkedSignal vs computed

Problem Statement

In Angular Signals, you have multiple tools to manage reactive state: signal, computed, and the newer linkedSignal. When deriving state from other signals, why choose linkedSignal instead of computed? The confusion arises when managing values derived from another signal (like a selection that depends on a dynamic list of options) that also need explicit local updates.

Consider a scenario with a list of shipping options and a selected option:

typescript
const shippingOptions = signal(['Ground', 'Air', 'Sea']);
// Why not always use computed?
const selectedOption = computed(() => shippingOptions()[0]);

The key dilemma: computed works for pure derivations, but fails when you need:

  1. Direct write access to the derived value
  2. Custom logic to handle source data changes
  3. State consistency when underlying data changes

Solution: When to Use linkedSignal

Key Conceptual Differences

computedlinkedSignal
MutabilityRead-onlyWritable
DependenciesAuto-trackedExplicitly defined
Update ControlRecalculated on every dependency changeCustomizable recalculation logic
Previous Value AccessNoYes
Best ForPure derivationsLocal mutable state with external dependencies

When linkedSignal Outperforms computed

Use linkedSignal when you need:

  1. Local writable state that depends on external signals
  2. Fallback logic when source data changes
  3. Manual updates to derived values

Basic Usage Pattern

typescript
const shippingOptions = signal(['Ground', 'Air', 'Sea']);
const selectedOption = linkedSignal(
  () => shippingOptions()[0] // Default derivation
);

// Unlike computed, you can update it:
selectedOption.set('Air');

Practical Implementation

Scenario: Dynamic List Selection

typescript
const animals = signal(['Cat', 'Dog', 'Pig']);

// Without linkedSignal (problematic implementation)
const selectedAnimal = signal(animals()[0]); 

removeAnimal('Cat') {
  animals.update(list => list.filter(a => a !== 'Cat'));
  // Problem: selectedAnimal still points to 'Cat'
}

SELECTION CORRUPTION RISK

When the source list changes, selections referencing missing items become invalid. linkedSignal solves this automatically.

Improved linkedSignal Implementation

typescript
const selectedAnimal = linkedSignal<string[], string>({
  source: animals,
  computation: (newList, previousValue) => {
    // On initial run
    if (!previousValue) return newList[0];
    
    // If previous selection exists, keep it
    if (newList.includes(previousValue.value)) {
      return previousValue.value;
    }
    
    // Fallback to first item
    return newList[0];
  }
});

Comparison With Other Approaches

ApproachExample ScenarioLimitation
computedDerived read-only valueNo write capability
signal + manual syncSimple selectionComplex synchronization
linkedSignalSelection in dynamic listsNative value consistency

Use Case Breakdown

Typical linkedSignal Applications

  1. Item Selection in CRUD Interfaces
    Automatically update selections when items are deleted

  2. Configurable Default Values

    typescript
    const defaultTheme = signal('light');
    const userTheme = linkedSignal(() => defaultTheme());
    
    // User can override temporarily
    userTheme.set('dark');
  3. Contextual State Preservation
    Maintain selections during data refreshes when possible

DESIGN PATTERN

Think of linkedSignal as a reactive two-way bridge:

  1. Top-down: Reacts to source signal changes
  2. Bottom-up: Allows local overrides

Advanced: Controlled Computation Pattern

For complex state reconciliation:

typescript
linkedSignal({
  source: [signalA, signalB], // Multiple sources
  computation: ([aVal, bVal], prev) => {
    if (customCondition(aVal, bVal, prev?.value)) {
      return customValue; 
    }
    return fallbackValue;
  }
})

Key Takeaways

  1. Use computed for pure derivations without write requirements
  2. Use linkedSignal for mutable derived state that requires:
    • Write capabilities
    • Automatic source change handling
    • Custom fallback logic
  3. Always provide value validation in computation logic to prevent stale references

Implement linkedSignal whenever managing user selections, configurable defaults, or any state needing synchronization with source data while allowing local override. In standard derivation scenarios without write requirements, computed remains the simpler choice.