Angular Signals
Learn Angular Signals with practical examples, computed signals, effects, writable signals, architecture diagrams, performance optimization, enterprise use cases, best practices, and interview questions.
Angular Signals are a modern reactive state management feature introduced in Angular 16 and enhanced in later Angular releases.
Signals provide:
- Fine-grained reactivity
- Automatic dependency tracking
- Better performance
- Simpler state management
- Reduced change detection work
- Cleaner component code
Unlike RxJS Observables, Signals are synchronous state containers designed primarily for local and shared application state.
Angular Signals have become one of the hottest Angular interview topics.
Table of Contents
- What are Angular Signals?
- Why Signals?
- Signals Architecture
- Creating Signals
- Reading Signals
- Updating Signals
- Computed Signals
- Effects
- Writable vs Readonly Signals
- Signals vs RxJS
- Enterprise Banking Example
- Performance Best Practices
- Common Mistakes
- Top 10 Interview Questions
- Summary
What are Angular Signals?
A Signal is a reactive value that automatically notifies Angular whenever its value changes.
Instead of manually subscribing,
Angular tracks dependencies automatically.
Example
const counter = signal(0);
Whenever the value changes,
Angular updates only the parts of the UI that depend on it.
Signals Architecture
flowchart LR
Signal
Signal --> Computed
Computed --> Component
Signal --> Effect
Effect --> SideEffects
Why Signals?
Traditional Angular applications often rely on:
- RxJS
- BehaviorSubject
- Manual subscriptions
- Change Detection
Signals provide:
- Simpler syntax
- Automatic dependency tracking
- No manual subscriptions
- Better rendering performance
- Fine-grained updates
Creating a Signal
import {
signal
} from '@angular/core';
counter =
signal(0);
Initial value
0
Reading a Signal
Signals are read like functions.
console.log(
this.counter()
);
Template
<p>
{{ counter() }}
</p>
Unlike Observables, no async pipe is required.
Signal Read Flow
flowchart LR
Signal
Signal --> Component
Component --> Template
Updating a Signal
set()
Replace the value.
counter.set(10);
update()
Update based on the previous value.
counter.update(
value => value + 1
);
mutate() (Angular 16 only)
Earlier Angular versions supported mutate() for directly changing objects or arrays.
Modern Angular applications should prefer immutable updates using set() or update().
Updating Architecture
flowchart TD
A["Signal State"]
B["set(newValue)"]
C["update(fn)"]
D["Signal Value Updated"]
E["Angular Change Detection"]
F["UI Re-rendered"]
A --> B
A --> C
B --> D
C --> D
D --> E
E --> F
Writable Signals
Writable Signals can be updated.
name =
signal('Venu');
name.set(
'John'
);
Readonly Signals
Readonly Signals expose state without allowing modification.
private count =
signal(0);
readonlyCount =
this.count.asReadonly();
Components can read the value but cannot call set() or update() on the readonly signal.
Computed Signals
A Computed Signal derives its value from other Signals.
price =
signal(100);
tax =
signal(10);
total =
computed(
() =>
this.price()
+
this.tax()
);
Whenever price or tax changes,
total automatically recalculates.
Computed Signal Architecture
flowchart TD
PriceSignal
TaxSignal
PriceSignal --> Computed
TaxSignal --> Computed
Computed --> UI
Computed Example
firstName =
signal('John');
lastName =
signal('Doe');
fullName =
computed(
() =>
`${this.firstName()}
${this.lastName()}`
);
Output
John Doe
No manual synchronization is required.
Effects
Effects perform side effects whenever dependent Signals change.
effect(() => {
console.log(
this.counter()
);
});
Whenever counter changes,
the effect runs automatically.
Effect Architecture
flowchart LR
Signal
Signal --> Effect
Effect --> Logging
Effect --> API
Effect --> LocalStorage
Effect Example
theme =
signal('light');
effect(() => {
localStorage.setItem(
'theme',
this.theme()
);
});
Changing the signal automatically updates local storage.
Best Practice: Use effects for side effects such as logging, analytics, or persistence—not for deriving application state. Prefer
computed()for derived values.
Signals with Components
@Component({
selector:'app-counter',
template:`
<button
(click)="increment()">
+
</button>
<p>
{{count()}}
</p>
`
})
export class CounterComponent{
count =
signal(0);
increment(){
this.count.update(
value => value + 1
);
}
}
Angular automatically refreshes the displayed value when the signal changes.
Signals vs RxJS
| Feature | Signals | RxJS Observables |
|---|---|---|
| Reactive | Yes | Yes |
| Async Data | Limited | Excellent |
| HTTP Streams | No | Yes |
| State Management | Excellent | Excellent |
| Subscriptions | Not Required | Required (or Async Pipe) |
| Dependency Tracking | Automatic | Manual Composition |
| Learning Curve | Easier | Steeper |
When to Use Signals
Use Signals for:
- Component state
- UI state
- Theme switching
- Form state
- Selected items
- Filters
- Counters
- Shared UI state
Continue using RxJS for:
- HTTP requests
- WebSockets
- Event streams
- Timers
- Complex asynchronous workflows
Signals and RxJS complement each other—they are not replacements for one another.
Enterprise Banking Example
Online Banking Dashboard
Signals Manage
- Selected Account
- Dashboard Theme
- Current Customer
- Sidebar State
- Selected Currency
- Notification Count
RxJS Handles
- HTTP APIs
- Live Stock Prices
- WebSockets
- Transaction Streams
Architecture
flowchart TD
AngularApp
AngularApp --> Signals
AngularApp --> RxJS
Signals --> Components
RxJS --> BankingAPI
BankingAPI --> Database
Database --> Components
Benefits
- Faster rendering
- Less boilerplate
- Better maintainability
- Reactive UI
- Cleaner architecture
Performance Best Practices
| Practice | Benefit |
|---|---|
Use computed() for derived values |
Automatic recalculation |
Use effect() only for side effects |
Cleaner architecture |
| Prefer immutable updates | Predictable state |
| Expose readonly signals | Better encapsulation |
| Keep state small and focused | Better performance |
| Combine Signals with RxJS appropriately | Best of both approaches |
Common Mistakes
Using Effects for Derived State
❌ Bad
effect(() => {
this.total.set(
this.price()
+
this.tax()
);
});
✅ Good
total =
computed(
() =>
this.price()
+
this.tax()
);
Making Every Value a Signal
Only state that changes reactively should become a Signal.
Static constants usually do not need Signals.
Modifying Readonly Signals
Readonly Signals cannot be updated directly.
Expose readonly signals to consumers while keeping writable signals private.
Replacing RxJS Completely
Signals are not intended to replace:
- HTTP Observables
- WebSockets
- Event streams
- Complex asynchronous pipelines
Use the appropriate tool for each problem.
Large Monolithic Signals
Avoid storing the entire application state in one huge Signal.
Split state into focused Signals.
Best Practices
- Keep writable signals private where appropriate.
- Expose readonly signals to consumers.
- Use
computed()for derived values. - Use
effect()only for side effects. - Prefer immutable updates.
- Keep Signals focused.
- Use RxJS for asynchronous streams.
- Avoid unnecessary effects.
- Write unit tests.
- Choose Signals or RxJS based on the use case.
Advantages
| Feature | Benefit |
|---|---|
| Fine-Grained Reactivity | Better rendering performance |
| No Subscriptions | Less boilerplate |
| Computed Signals | Automatic derived state |
| Effects | Simple side effects |
| Readonly Signals | Better encapsulation |
| Enterprise Ready | Cleaner architecture |
Top 10 Angular Signals Interview Questions
1. What are Angular Signals?
Answer
Signals are reactive state containers that automatically notify Angular when their values change, enabling fine-grained UI updates.
2. How do you create a Signal?
Answer
const counter = signal(0);
3. How do you update a Signal?
Answer
Use set() to replace the value or update() to calculate a new value from the current one.
4. What is a Computed Signal?
Answer
A Computed Signal derives its value automatically from one or more other Signals.
5. What is an Effect?
Answer
An Effect executes side-effect logic whenever one of its dependent Signals changes.
6. Do Signals require subscriptions?
Answer
No. Angular automatically tracks dependencies and updates consumers without manual subscriptions.
7. What is the difference between Signals and RxJS?
Answer
Signals are best for synchronous application and UI state, while RxJS is designed for asynchronous streams such as HTTP requests, WebSockets, and events.
8. What are Readonly Signals?
Answer
Readonly Signals expose reactive state without allowing external code to modify it.
9. What are common enterprise use cases?
Answer
- Dashboard state
- Theme switching
- Selected customer
- Navigation state
- Notification counters
- UI filters
10. What are Angular Signals best practices?
Answer
- Use
computed()for derived state. - Use
effect()only for side effects. - Keep writable signals private.
- Expose readonly signals.
- Combine Signals with RxJS appropriately.
Interview Cheat Sheet
| Topic | Remember |
|---|---|
| Create | signal() |
| Read | signal() (function call) |
| Replace Value | set() |
| Update Value | update() |
| Derived State | computed() |
| Side Effects | effect() |
| Readonly | asReadonly() |
| UI State | Excellent Choice |
| HTTP | Use RxJS |
| Subscriptions | Not Required |
Summary
Angular Signals introduce a simpler and more efficient reactive programming model for managing application state. By providing automatic dependency tracking, computed values, and effects, Signals reduce boilerplate while improving rendering performance. They are ideal for UI and application state, while RxJS continues to be the preferred choice for asynchronous streams such as HTTP requests and WebSockets. Using both together results in clean, scalable, and enterprise-ready Angular applications.
Key Takeaways
- ✔ Signals provide fine-grained reactivity.
- ✔ Signals eliminate manual subscriptions for state management.
- ✔
set()replaces values. - ✔
update()modifies values based on previous state. - ✔
computed()creates derived state. - ✔
effect()handles side effects. - ✔ Expose readonly signals for encapsulation.
- ✔ Use immutable updates.
- ✔ Combine Signals with RxJS instead of replacing it.
- ✔ Angular Signals are a top Angular interview topic.
Next Article
➡️ 81-Signals-vs-RxJS-QA.md