What are Angular signals and how do they differ from Observables?
Understand Angular signals, the reactive primitive with a synchronous current value, and how they differ from RxJS Observables for state and async streams.
Expected Interview Answer
Angular signals are a built-in reactive primitive that hold a value, notify consumers when it changes, and are read synchronously by calling them as a function; Observables are RxJS streams of values over time that you subscribe to and compose with operators.
A signal always has a current value you can read immediately with mySignal(), and computed() signals derive from others while effect() runs side effects when dependencies change. Angular tracks which signals a template reads and updates only those views, enabling fine-grained, zoneless change detection. Observables, by contrast, are push-based streams that may emit zero, one, or many values asynchronously, do nothing until subscribed, and shine at async coordination like HTTP, debouncing, and merging. Signals are ideal for synchronous UI state; Observables are ideal for event streams and async pipelines, and you bridge them with toSignal() and toObservable().
- Synchronous reads with a guaranteed current value
- Fine-grained change detection and zoneless support
- Simple computed derivations without operators
- Less boilerplate than manual subscriptions for local state
- Interoperable with RxJS via toSignal and toObservable
AI Mentor Explanation
A signal is the current scoreboard total: glance at it any moment and it shows the exact runs right now. An Observable is the ball-by-ball commentary stream: it narrates each event as it happens over time, and you only hear it while you are tuned in, but it has no single 'current value' to read on demand.
Step-by-Step Explanation
Step 1
Create a writable signal
Use const count = signal(0); to hold a reactive value with an initial state.
Step 2
Read synchronously
Call count() to get the current value; in a template {{ count() }} tracks it automatically.
Step 3
Update the value
Use count.set(5) or count.update(c => c + 1) to change it and notify consumers.
Step 4
Derive with computed
const doubled = computed(() => count() * 2); recomputes lazily when count changes.
Step 5
Run side effects
effect(() => console.log(count())) reacts whenever a read signal changes.
Step 6
Bridge to RxJS
Use toSignal(obs$) and toObservable(sig) to interoperate with Observables when needed.
What Interviewer Expects
- Signals are synchronous with a current value; Observables are async streams
- Knowledge of signal, computed, and effect
- How signals enable fine-grained and zoneless change detection
- When to use each: local UI state vs async event pipelines
- Interop via toSignal and toObservable
Common Mistakes
- Saying signals replace RxJS entirely
- Forgetting to call the signal as a function to read its value
- Putting async logic like HTTP directly in signals instead of Observables
- Thinking Observables always have a readable current value
- Mutating objects in a signal without calling set/update
Best Answer (HR Friendly)
“Angular signals are simple holders of a value that automatically tell the UI when that value changes, and you read them like calling a function. They differ from Observables, which are streams of events over time; signals are best for current on-screen state, while Observables are best for handling things like network requests and event streams.”
Code Example
import { signal, computed, effect } from '@angular/core';
const count = signal(0);
const doubled = computed(() => count() * 2);
effect(() => {
console.log(`count is ${count()}, doubled is ${doubled()}`);
});
count.set(3); // logs: count is 3, doubled is 6
count.update((c) => c + 1); // logs: count is 4, doubled is 8Follow-up Questions
- When would you choose a signal over an Observable?
- How does computed() differ from effect()?
- How do signals enable zoneless change detection?
- How do you convert between signals and Observables?
- What is the difference between set and update on a writable signal?
MCQ Practice
1. How do you read the current value of a signal named count?
Signals are read by calling them as a function: count() returns the current value.
2. Which statement best distinguishes signals from Observables?
Signals always have a readable current value read synchronously; Observables push zero or more values over time.
3. What is computed() used for?
computed() creates a derived signal that recalculates lazily when its source signals change.
Flash Cards
What is an Angular signal? — A reactive primitive holding a value, read synchronously by calling it, that notifies consumers on change.
How do you read a signal's value? — Call it as a function, e.g. mySignal().
Signal vs Observable? — Signal = current synchronous value; Observable = async stream of values over time.
What does computed() do? — Creates a derived signal recalculated lazily when its dependencies change.
How do signals and RxJS interoperate? — Use toSignal() to convert an Observable to a signal and toObservable() for the reverse.
Continue Learning
Related Interview Questions
What is the async pipe in Angular and why is it recommended?
easy
How do computed signals and effects differ in Angular, and when does each actually run?
hard
What are Observables and how does RxJS power Angular's async handling?
medium
What is the difference between an Observable and a Promise in Angular?
medium