Signal Basics

Back

Loading concept...

🚦 Angular Signals: Your App’s Magic Walkie-Talkies

Imagine your Angular app is a busy kitchen. Signals are like magical walkie-talkies that instantly tell everyone when something changes—no shouting needed!


🌟 The Story: Meet Chef Angular’s Kitchen

Once upon a time, there was a busy restaurant kitchen. Chef Angular had a problem: whenever an ingredient changed, nobody knew! The soup chef didn’t know the salt was gone. The salad chef didn’t know new tomatoes arrived.

Then one day, Chef Angular discovered Signals—magical walkie-talkies that automatically broadcast changes to everyone who needs to know.

Let’s learn how these magic walkie-talkies work!


đź“» What Are Signals? (Signals Fundamentals)

The Simple Truth

A Signal is like a special box that:

  1. Holds a value (like a toy box holds toys)
  2. Tells everyone when the value changes (like a doorbell rings when someone arrives)

Why Do We Need Signals?

Without Signals (the old way):

  • You change something in your app
  • Angular has to check EVERYTHING to find what changed
  • It’s like searching the whole house to find which light was turned on

With Signals (the new way):

  • You change something
  • The Signal immediately tells only the parts that care
  • It’s like the light switch directly calling your eyes!
graph TD A["📦 Signal Value Changes"] --> B["🔔 Signal Notifies"] B --> C["👀 Only Interested Parts Update"] C --> D["⚡ Super Fast App!"]

Real Life Example

Think of a scoreboard at a sports game:

  • The score is stored in a Signal
  • When the score changes, only the scoreboard updates
  • The hot dog stand doesn’t need to refresh!

🎨 Creating Signals: Making Your First Walkie-Talkie

The Magic Spell

Creating a Signal is easy! You use the signal() function:

import { signal } from '@angular/core';

// Create a Signal with value 0
const score = signal(0);

// Create a Signal with text
const playerName = signal('Mario');

// Create a Signal with a list
const fruits = signal(['apple', 'banana']);

Reading the Value

To see what’s inside your Signal box, you call it like a function:

// Create the signal
const age = signal(10);

// Read the value (add parentheses!)
console.log(age());  // Shows: 10

// In your HTML template:
// {{ age() }}

Why the Parentheses?

Think of it like opening a box:

  • age = the closed box
  • age() = opening the box to see inside!

Full Example: A Counter

import { Component, signal } from '@angular/core';

@Component({
  selector: 'app-counter',
  template: `
    <h1>Count: {{ count() }}</h1>
  `
})
export class CounterComponent {
  count = signal(0);
}

🔄 Updating Signals: Changing the Message

Now your walkie-talkie can broadcast! But how do you change the message?

Three Ways to Update

Method What It Does Use When
.set() Replace completely You know the new value
.update() Change based on old value Math or modifications
.mutate() Change inside objects/arrays Editing items in a list

Method 1: .set() - Complete Replacement

Like replacing all the toys in your box with new ones:

const temperature = signal(20);

// Set to a brand new value
temperature.set(25);

console.log(temperature()); // 25

Method 2: .update() - Calculate New Value

Like adding to your piggy bank—you need to know what’s already there:

const coins = signal(5);

// Add 3 more coins
coins.update(current => current + 3);

console.log(coins()); // 8

The arrow function receives the current value, and you return the new value!

Method 3: .mutate() - Edit In Place

Like adding a sticker to a toy instead of replacing the whole toy:

const todos = signal([
  { task: 'Buy milk', done: false }
]);

// Add a new item to the array
todos.mutate(list => {
  list.push({ task: 'Walk dog', done: false });
});

Quick Reference Card

const name = signal('Anna');

// Complete replacement
name.set('Beth');        // Now: 'Beth'

// Transform the current value
name.update(n => n + '!'); // Now: 'Beth!'

// For objects/arrays
const items = signal([1, 2]);
items.mutate(arr => arr.push(3)); // Now: [1, 2, 3]

đź§® Computed Signals: Auto-Calculating Magic

The Problem

Imagine you have:

  • A price Signal: $10
  • A quantity Signal: 3

You want the total to automatically update when either changes. This is where computed signals shine!

What is a Computed Signal?

A computed signal is like a calculator that automatically recalculates whenever its ingredients change.

import { signal, computed } from '@angular/core';

const price = signal(10);
const quantity = signal(3);

// This automatically recalculates!
const total = computed(() => price() * quantity());

console.log(total()); // 30

price.set(20);
console.log(total()); // 60 (auto-updated!)
graph TD A["🏷️ price Signal"] --> C["🧮 computed total"] B["📦 quantity Signal"] --> C C --> D["💰 Auto-calculated Result"]

Key Rules for Computed

  1. Read-only: You can’t .set() a computed signal
  2. Lazy: Only calculates when you actually read it
  3. Cached: Remembers the answer until inputs change

Real World Example: Shopping Cart

const items = signal([
  { name: 'Apple', price: 1 },
  { name: 'Bread', price: 3 },
  { name: 'Milk', price: 2 }
]);

// Total automatically updates
const cartTotal = computed(() => {
  return items().reduce(
    (sum, item) => sum + item.price,
    0
  );
});

console.log(cartTotal()); // 6

// Add an item
items.mutate(list => {
  list.push({ name: 'Eggs', price: 4 });
});

console.log(cartTotal()); // 10 (auto-updated!)

Computed Can Use Other Computed!

const subtotal = computed(() => cartTotal());
const tax = computed(() => subtotal() * 0.1);
const grandTotal = computed(() => subtotal() + tax());

⚡ Effects: Reacting to Changes

What Are Effects?

Effects are like automatic reactions. When a Signal changes, the effect runs automatically.

Think of it like a motion sensor light:

  • The sensor watches for movement (Signal)
  • When movement happens, the light turns on (Effect runs)

Creating an Effect

import { signal, effect } from '@angular/core';

const username = signal('Guest');

// This runs whenever username changes
effect(() => {
  console.log(`Hello, ${username()}!`);
});

// Output: "Hello, Guest!"

username.set('Alice');
// Output: "Hello, Alice!" (automatic!)

When to Use Effects

Use Effects For Example
Logging Save changes to console
Saving data Sync to localStorage
External calls Update a chart library
Analytics Track user actions

Real Example: Auto-Save

const notes = signal('');

// Auto-save to localStorage
effect(() => {
  localStorage.setItem(
    'my-notes',
    notes()
  );
});

// Every time notes changes,
// it's automatically saved!
notes.set('Buy groceries');
// Saved automatically!

Effect Cleanup

Effects can return a cleanup function:

effect((onCleanup) => {
  const timer = setInterval(() => {
    console.log(`Time: ${clock()}`);
  }, 1000);

  // Cleanup when effect re-runs or destroys
  onCleanup(() => clearInterval(timer));
});
graph TD A["📡 Signal Changes"] --> B["⚡ Effect Runs"] B --> C["🎬 Side Effect Happens"] C --> D["📝 Console log"] C --> E["💾 Save to storage"] C --> F["📊 Update chart"]

🎯 Putting It All Together

Here’s a complete example combining everything:

import {
  Component,
  signal,
  computed,
  effect
} from '@angular/core';

@Component({
  selector: 'app-game',
  template: `
    <h1>{{ playerName() }}'s Score</h1>
    <p>Points: {{ score() }}</p>
    <p>Level: {{ level() }}</p>
    <button (click)="addPoints()">
      +10 Points
    </button>
  `
})
export class GameComponent {
  // Basic signals
  playerName = signal('Hero');
  score = signal(0);

  // Computed: auto-calculates level
  level = computed(() => {
    return Math.floor(this.score() / 100) + 1;
  });

  constructor() {
    // Effect: celebrate level ups!
    effect(() => {
      if (this.level() > 1) {
        console.log(`🎉 Level ${this.level()}!`);
      }
    });
  }

  addPoints() {
    this.score.update(s => s + 10);
  }
}

🏆 Summary: Your Signal Toolkit

Concept What It Does Code
Signal Holds reactive value signal(0)
Read Get current value count()
Set Replace value .set(5)
Update Transform value .update(n => n+1)
Mutate Edit arrays/objects .mutate(arr => ...)
Computed Auto-calculate computed(() => ...)
Effect React to changes effect(() => ...)

đź’ˇ Remember This!

Signals are like smart walkie-talkies:

  • They hold a message (value)
  • They broadcast when it changes
  • Only listeners who care will hear it
  • Everything stays in sync automatically!

You now have the power to build reactive, efficient, and easy-to-understand Angular apps. Go forth and signal! 🚦✨

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.