Getting Started

Angular Basic Syntax

Learn the fundamental syntax of Angular — decorators, component metadata, template expressions, and how TypeScript integrates with Angular's framework APIs.

Angular Syntax Fundamentals

Angular uses TypeScript as its primary language and leverages decorators, metadata, and template syntax to define applications. This topic covers the core syntax patterns you'll use throughout every Angular project.

Decorators

Decorators are special functions prefixed with @ that attach metadata to classes. They tell Angular how to process a class.

@Component

Defines a visual building block of the UI:

typescript
import { Component } from '@angular/core';

@Component({
  selector: 'app-greeting',
  standalone: true,
  template: `<h2>Welcome to Angular!</h2>`,
  styles: [`h2 { color: #1976d2; }`],
})
export class GreetingComponent {}
PropertyPurpose
selectorThe custom HTML tag to use this component
standaloneWhether this is a standalone component
templateInline HTML template
templateUrlPath to an external HTML template file
stylesInline CSS styles
styleUrlPath to an external CSS style file
importsOther components/modules this component uses

@Injectable

Marks a class as available for dependency injection:

typescript
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class DataService {
  getData() {
    return ['Item 1', 'Item 2', 'Item 3'];
  }
}

Template Expressions

Angular templates use special syntax to connect the component class to the HTML view.

Interpolation — {{ }}

Displays the value of a component property in the template:

html
<h1>Hello, {{ username }}!</h1>
<p>2 + 2 = {{ 2 + 2 }}</p>
<p>Today is {{ today.toLocaleDateString() }}</p>
typescript
@Component({ /* ... */ })
export class AppComponent {
  username = 'Developer';
  today = new Date();
}

Property Binding — [property]

Binds a DOM property to a component expression:

html
<img [src]="imageUrl" [alt]="imageAlt">
<button [disabled]="isLoading">Submit</button>
<div [class.active]="isActive">Content</div>
<p [style.color]="textColor">Styled text</p>

Event Binding — (event)

Listens for DOM events and calls a component method:

html
<button (click)="onSave()">Save</button>
<input (input)="onInput($event)">
<form (submit)="onSubmit()">...</form>
<div (mouseenter)="onHover()" (mouseleave)="onLeave()">
  Hover me
</div>
typescript
export class AppComponent {
  onSave() {
    console.log('Saved!');
  }

  onInput(event: Event) {
    const value = (event.target as HTMLInputElement).value;
    console.log(value);
  }
}

Two-Way Binding — [(ngModel)]

Combines property binding and event binding for form inputs:

html
<input [(ngModel)]="searchTerm" placeholder="Search...">
<p>Searching for: {{ searchTerm }}</p>

Note: Two-way binding with ngModel requires importing FormsModule.

Control Flow in Templates

Angular 17+ introduced a new built-in control flow syntax:

@if / @else

html
@if (isLoggedIn) {
  <p>Welcome back, {{ user.name }}!</p>
} @else {
  <p>Please log in to continue.</p>
}

@for

html
<ul>
  @for (item of items; track item.id) {
    <li>{{ item.name }} — {{ item.price | currency }}</li>
  } @empty {
    <li>No items found.</li>
  }
</ul>

@switch

html
@switch (status) {
  @case ('active') {
    <span class="badge green">Active</span>
  }
  @case ('pending') {
    <span class="badge yellow">Pending</span>
  }
  @default {
    <span class="badge gray">Unknown</span>
  }
}

Note: The older *ngIf, *ngFor, and [ngSwitch] directives still work but the new syntax is preferred.

Template Reference Variables

Use # to create a reference to a DOM element:

html
<input #nameInput type="text" placeholder="Your name">
<button (click)="greet(nameInput.value)">Greet</button>

Pipes

Pipes transform data in templates:

html
<p>{{ title | uppercase }}</p>
<p>{{ price | currency:'USD' }}</p>
<p>{{ birthday | date:'longDate' }}</p>
<p>{{ data | json }}</p>

Component Interaction Summary

Component Class (TypeScript)
    │
    ├── {{ expression }}      → Interpolation (display data)
    ├── [property]="expr"     → Property binding (set DOM props)
    ├── (event)="handler()"   → Event binding (respond to actions)
    └── [(ngModel)]="prop"    → Two-way binding (sync input ↔ model)
    │
Template (HTML)

Example: Putting It All Together

typescript
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-counter',
  standalone: true,
  imports: [FormsModule],
  template: `
    <div>
      <h2>Counter: {{ count }}</h2>
      <button (click)="increment()">+</button>
      <button (click)="decrement()" [disabled]="count === 0">-</button>
      <hr>
      <label>Set value: </label>
      <input [(ngModel)]="count" type="number">
    </div>
  `,
})
export class CounterComponent {
  count = 0;

  increment() {
    this.count++;
  }

  decrement() {
    this.count--;
  }
}

Next Steps

Now that you understand Angular's basic syntax, we'll explore TypeScript in depth — the language that powers every Angular application.