← Back to Chapters

Getter/Setter

? Getter/Setter

Angular TypeScript Component Logic

? Quick Overview

In Angular components, getters and setters let you run extra logic whenever a property is read or updated. They are useful for:

  • Validation (e.g., preventing invalid values)
  • Computed values (e.g., fullName from first and last name)
  • Formatting (e.g., trimming whitespace, capitalization)
  • Controlling exposure of internal/private fields to the template

? Key Concepts

  • A getter uses the get keyword and runs whenever the property is read (e.g., in template bindings like {{ fullName }}).
  • A setter uses the set keyword and runs whenever the property is assigned (e.g., via [(ngModel)] or in TypeScript code).
  • You usually keep internal data in private backing fields (like _firstName) and expose them through public getters/setters.
  • Templates can bind directly to these public getters and setters using Angular’s interpolation {{ }} and two-way binding [(ngModel)].

? Syntax & Theory

A basic getter/setter pair in a TypeScript (Angular) component looks like this:

? View Code Example
// Simple getter and setter pattern in a component
private _value: string = '';

get value(): string {
  // Compute or transform data before returning
  return this._value.toUpperCase();
}

set value(newValue: string) {
  // Validate or sanitize input before storing
  this._value = newValue.trim();
}

Key points:

  • The getter’s return type is the type of the exposed property.
  • The setter takes exactly one parameter, which is the new value being assigned.
  • Angular’s change detection may call getters often, so you should keep their logic lightweight.

? Example 1: Getter/Setter in a User Component

This component stores first and last name using private fields and exposes them with getters/setters. It also computes a fullName using a getter.

? View Code Example
// user.component.ts - using getters/setters and a computed fullName
import { Component } from '@angular/core';

@Component({
  selector: 'app-user',
  template: `
    <h2>Welcome {{ fullName }}</h2>
    <input [(ngModel)]="firstName" placeholder="First Name">
    <input [(ngModel)]="lastName" placeholder="Last Name">
  `
})
export class UserComponent {
  private _firstName: string = '';
  private _lastName: string = '';

  get firstName(): string {
    // Expose the private _firstName field
    return this._firstName;
  }

  set firstName(value: string) {
    // Trim whitespace before storing the value
    this._firstName = value.trim();
  }

  get lastName(): string {
    // Expose the private _lastName field
    return this._lastName;
  }

  set lastName(value: string) {
    // Also trim whitespace for the last name
    this._lastName = value.trim();
  }

  get fullName(): string {
    // Compute a derived property from first and last name
    return this.firstName + ' ' + this.lastName;
  }
}

?️ Example 2: Validating Input with a Setter

Here, the setter ensures that the product price can never be negative. If the user enters a negative value, the setter forces it back to 0.

? View Code Example
// product.component.ts - using a setter to validate numeric input
import { Component } from '@angular/core';

@Component({
  selector: 'app-product',
  template: `
    <p>Product Price: {{ price }}</p>
    <input type="number" [(ngModel)]="price">
  `
})
export class ProductComponent {
  private _price: number = 0;

  get price(): number {
    // Return the validated price value
    return this._price;
  }

  set price(value: number) {
    // Prevent negative prices from being stored
    if (value < 0) {
      this._price = 0;
    } else {
      this._price = value;
    }
  }
}

? Live Output & Explanation

What happens in the template?

  • In UserComponent, when the user types into the First Name input:
    • [(ngModel)]="firstName" calls the setter with the new value.
    • The setter trims whitespace and stores it in _firstName.
    • The getter for fullName is called, recomputing the full name.
    • The template shows: Welcome John Doe (for example).
  • In ProductComponent, if the user enters -50:
    • The setter for price receives -50.
    • The if check detects that it is negative and stores 0 instead.
    • The template still shows: Product Price: 0.

✅ Tips & Best Practices

  • Use setters to validate or sanitize inputs (trimming whitespace, enforcing ranges, preventing negatives, etc.).
  • Use getters for derived values like fullName, formatted currency, or combined labels.
  • Always keep getter logic fast and simple – they may run frequently during change detection.
  • Prefer private backing fields (e.g., _price) to avoid infinite loops or accidental recursion in setters.
  • When sanitizing data in setters, handle null and undefined carefully to avoid runtime errors.

?‍? Try It Yourself

  • Create a StudentComponent with firstName and lastName setters that automatically capitalize names (e.g., johnJohn).
  • Build a TemperatureComponent that stores temperature in Celsius but exposes a getter for Fahrenheit (and optionally a setter that converts back).
  • Add a username property with a setter that rejects empty strings and replaces them with a default username like "Guest".
  • Experiment with logging inside getters/setters (e.g., console.log) to see how often they are called during change detection.