A New Starting Project & Analyzing The Project Structure
Understanding Components & How Content Ends Up On The Screen
Creating a First Custom Component
[Optional] JavaScript Refresher: Classes Properties & More
Configuring the Custom Component
Using the Custom Component
Styling the Header Component & Adding An Image
Managing & Creating Components with the Angular CLI
Styling & Using Our Next Custom Component
Preparing User Data (To Output Dynamic Content)
Storing Data in a Component Class
Outputting Dynamic Content with String Interpolation
Property Binding & Outputting Computed Values
Using Getters For Computed Values
Listening to Events with Event Binding
Managing State & Changing Data
A Look Behind The Scenes Of Angular's Change Detection Mechanism
We Need More Flexible Components!
Defining Component Inputs
Required & Optional Inputs
Working with Outputs & Emitting Data
Using the output() Function
Adding Extra Type Information To EventEmitter
Exercise: Create a Configurable Component
TypeScript: Working With Potentially Undefined Values & Union Types
Accepting Objects As Inputs & Adding Appropriate Typings
TypeScript: Type Aliases & Interfaces
Outputting Conditional Content
Legacy Angular: Using ngFor & ngIf
Adding More Components to the Demo App
Outputting User-specific Tasks
Outputting Task Data in the Task Component
Storing Data Models in Separate Files
Dynamic CSS Styling with Class Bindings
More Component Communication: Deleting Tasks
Creating & Conditionally Rendering Another Component
Managing The "New Task" Dialog
Using Directives & Two-Way-Binding
Signals & Two-Way-Binding
Content Projection with ng-content
Transforming Template Data with Pipes
Getting Started with Services
Getting Started with Dependency Injection
More Service Usage & Alternative Dependency Injection Mechanism
Time to Practice: Services
Using localStorage for Data Storage
A First Introduction To Angular Modules (NgModule)
Creating a First Empty Module
Bootstrapping Apps with Angular Modules
Declaring & Using Components
Migrating All Components To Use Modules
Creating & Using Shared Modules
Creating More Complex Module-based App Structures
Module Introduction & Starting Project
Adding a Header Component With An Image
Adding a User Input Component
Extracting Values with Two-Way-Binding
Calculating the Annual Investment Data
Cross-Component Communication with Outputs
Creating & Using a Data Model
Passing Data from Parent to Child with Inputs
Outputting Data in a Table
Formatting Output with a Pipe
Using Signals & Resetting The Form After Submission
Using a Service for Cross-Component Communication
Using Signals in Services
Migrating to Angular Modules
Starting Project & An Opportunity For Smaller Components?
When & How To Split Up Components
Splitting A Component Into Multiple Components
Creating Reusable Components
Component Inputs: Repetition
Property Binding: Repetition
Using Content Projection & ng-content
Adding Forms to Components
A Possible But Not Ideal Way Of Extending Built-in Elements
Extending Built-in Elements with Custom Components via Attribute Selectors
Supporting Content Projection with Multiple Slots
Exploring Advanced Content Projection
Defining Content Projection Fallbacks
Multi-Element Custom Components & Content Projection
Scoping CSS Styles to Components
Understanding & Configuring View Encapsulation
Making Sense of Component Host Elements
Using Host Elements Like Regular Elements
Interacting With Host Elements From Inside Components
When (Not) To Rely On Host Elements
Interacting with Host Elements via @HostListener & @HostBinding
Accessing Host Elements Programmatically
Class Bindings: Repetition
There's More Than One Way Of Binding CSS Classes Dynamically
A Closer Look At Dynamic Inline Style Binding
Manipulating State & Using Literal Values
Introducing the Component Lifecycle: ngOnInit
Implementing Lifecycle Interfaces
Component Lifecycle - A Deep Dive
Component Cleanup with ngOnDestroy
Component Cleanup with DestroyRef
Handling Form Submissions: Repetition
Working with Template Variables
Extracting Input Values via Template Variables
Template Variables & Component Instances
Getting Access to Template Elements via ViewChild
Using The viewChild Signal Function
ViewChild vs ContentChild
A Closer Look at Decorator-based Queries & Lifecycle Hooks
The afterRender and afterNextRender Lifecycle Functions
Making Sense of Signal Effects
Signal Effects Cleanup Functions
TypeScript & Type Models: Repetition
Component Outputs: Repetition
A Closer Look At Template For Loops
Revisiting Inputs & Signals
Cross-Component Communication & State Management
Configuring Component Inputs & Outputs
Two-Way Binding: Repetition
Setting Up Custom Two-Way Binding
An Easier Way of Setting Up Custom Two-Way Binding
Analyzing a Built-in Attribute Directive: ngModel
Analyzing a Built-in Structural Directive: ngIf
Getting Started with Custom Directives
Using Attribute Directives To Change Element Behavior
Working with Inputs in Custom Directives
Directives & Dependency Injection
Building Another Directive
Building a Custom Structural Directive
Structural Directives & Syntactic Sugar
Host Directives & Composition
More Built-in Pipes Examples
Building a First Custom Pipe
Using Custom Pipes to Perform Custom Transformations
Accepting Parameters in Custom Pipes
Chaining Pipes & Being Aware of Limitations
Building a Pipe That Sorts Items
Understanding How Pipes Are Executed
Pipe Limitations & When Not To Use Them
The Starting Project & The Need For A Centralized Service
How NOT To Provide A Service
Using Angular's Dependency Injection Mechanism
Using The Alternative Dependency Injection Syntax
Outsourcing & Reusing Logic with Services
Angular Has Multiple Injectors!
There Are Multiple Ways Of Providing a Service
Providing Services via the Element Injector
Understanding the Element Injector's Behavior
Injecting Services Into Services
Analyzing Dependency Injection with the Angular DevTools
Using Custom DI Tokens & Providers
Preparing A Non-Class Value For Injection
Injecting Other Values (NOT Services)
Angular Modules (NgModule) & Dependency Injection
Working with Services Without Using Signals
Analyzing the Starting Project
Understanding How Angular Performs Change Detection
Change Detection During Development: ExpressionChangedAfterChecked Errors
Writing Efficient Template Bindings
Using the OnPush Strategy
Understanding the OnPush Strategy
Working with OnPush & Signals
Using Signals for Sharing Data Across Components (with OnPush)
The Problem With OnPush Cross-Component Data & Not Using Signals
Triggering Change Detection Manually & Using RxJS Subjects
Introducing The async Pipe
The Starting Projects: Frontend & Backend
How To Connect Angular Apps To A Backend
Optional: HTTP Essentials
Getting Started with Angular's Http Client
Providing the HttpClient when using NgModules
Sending a GET Request To Fetch Data
Configuring Http Requests
Transforming & Using Response Data
Showing a Loading Fallback
Sending Data To A Backend
More Data Fetching & Some Code Duplication
Outsourcing HTTP Request Logic Into A Service
Managing HTTP-loaded Data via a Service
Implementing Optimistic Updating
Potential Problems Introduced by Optimistic Updating
Improved Optimistic Updating
Implementing App-wide Error Management
Practice: Sending DELETE Requests
Introducing HTTP Interceptors
Optional: Class-based Interceptors
Introducing HTTP Response Interceptors
Template-driven vs Reactive Forms
Template-driven: Registering Form Controls
Getting Access to the Angular-managed Form
Extracting User Input Values
Validating Input with Form Validation Directives
Using the Form Validation Status To Provide User Feedback
Interacting With The Underlying Form Object In The Component
Updating Form Values Programmatically
Reactive Forms: Getting Started
Syncing Reactive Form Definition & Template
Handling Form Submission (Reactive Forms)
Adding Validators To Reactive Forms
Building Custom Validators
Creating & Using Async Validators
Interacting with the Form Programmatically
Connecting & Registering Inputs For A Complex Form
Working with Nested Form Groups
Practice: Adding More Validation
Creating Multi-Input Validators / Form Group Validators
Enabling Routing & Adding a First Route
Registering Multiple Routes
Adding Links The Right Way
Styling Active Navigation Links
Setting Up & Navigating To Dynamic Routes
Extracting Dynamic Route Parameters via Inputs
Extracting Dynamic Route Parameters via @Input()
Extracting Dynamic Route Parameters via Observables
Working with Nested Routes
Route Links & Relative Links
Accessing Parent Route Data From Inside Nested Routes
Loading Data Based On Route Parameters In Child Routes
Link Shortcuts & Programmatic Navigation
Adding A "Not Found" Route
Splitting Route Definitions Across Multiple Files
Activated Route vs Activated Route Snapshot
Extracting Query Parameters via Inputs
Extracting Query Parameters via Observables
Using Query Parameters For Data Manipulation
Adding Static Data To Routes
Resolving Route-related Dynamic Data
Optional: Class-based Resolvers
Accessing Route Data In Components
Controlling Route Resolver Execution
Setting & Resolving Titles
Optional: Class-based Guards
Making Sense of The CanDeactivate Guard
Improving The CanDeactivate Logic
Reloading Pages via the Angular Router & Configuring Programmatic Navigation
What Is Lazy Loading / Code Splitting?
Introducing Route-based Lazy Loading
Implementing Route-based Lazy Loading
Lazy Loading Entire Route Groups
Using Lazy Loading & Routing to Lazy-load Services
Introducing Deferrable Views
Defer Loading Until Viewport Visibility
Deferrable Views: Using Other Triggers
Prefetching Lazy-loaded Code
Deferrable Views: Summary
Preparing a Project For Deployment: Building It For Production
Building SPAs: Pros & Cons
Using "ng add" "ng deploy" & Angular's Built-in Deployment Support
Server-side Rendering (SSR) Introduction
Setting Up SSR For An Angular App
Building and Service an SSR App
Authoring SSR-ready Code (Beware of Pitfalls!)
SSR and Client-Server Mismatches
Static Site Generation (SSG) Introduction
Deployment Methods - A Summary
SSR & SSG Deployment Example
How an Angular App gets Loaded and Started
Components are Important!
Understanding the Role of AppModule and Component Declaration
Working with Standalone Components
Creating Components with the CLI & Nesting Components
Working with Component Templates
Working with Component Styles
Fully Understanding the Component Selector
[OPTIONAL] Assignment Solution
Property Binding vs String Interpolation
Bindable Properties and Events
Passing and Using Data with Event Binding
Important: FormsModule is Required for Two-Way-Binding!
Combining all Forms of Databinding
[OPTIONAL] Assignment Solution
Using ngIf to Output Data Conditionally
Enhancing ngIf with an Else Condition
Angular 17: Alternative "if" Syntax
Styling Elements Dynamically with ngStyle
Applying CSS Classes Dynamically with ngClass
Outputting Lists with ngFor
Angular 17: Alternative "for" Syntax
[OPTIONAL] Assignment Solution
Getting the Index when using ngFor
Creating a New App Correctly
Setting up the Application
Alternative Non-Collapsable Navigation Bar
Creating a "Recipe" Model
Adding Content to the Recipes Components
Outputting a List of Recipes with ngFor
Displaying Recipe Details
Working on the ShoppingListComponent
Creating an "Ingredient" Model
Creating and Outputting the Shopping List
Adding a Shopping List Edit Section
Splitting Apps into Components
Property & Event Binding Overview
Binding to Custom Properties
Assigning an Alias to Custom Properties
Assigning an Alias to Custom Events
Custom Property and Event Binding Summary
Understanding View Encapsulation
More on View Encapsulation
Using Local References in Templates
@ViewChild() in Angular 8+
Getting Access to the Template & DOM with @ViewChild
Projecting Content into Components with ng-content
Understanding the Component Lifecycle
Seeing Lifecycle Hooks in Action
Lifecycle Hooks and Template Access
@ContentChild() in Angular 8+
Getting Access to ng-content with @ContentChild
Practicing Property & Event Binding and View Encapsulation
[OPTIONAL] Assignment Solution
ngClass and ngStyle Recap
Creating a Basic Attribute Directive
Using the Renderer to build a Better Attribute Directive
Using HostListener to Listen to Host Events
Using HostBinding to Bind to Host Properties
Binding to Directive Properties
What Happens behind the Scenes on Structural Directives
Building a Structural Directive
Why would you Need Services?
Creating a Logging Service
Injecting the Logging Service into Components
Alternative Injection Syntax
Understanding the Hierarchical Injector
How many Instances of Service Should It Be?
Injecting Services into Services
Using Services for Cross-Component Communication
A Different Way Of Injecting Services
[OPTIONAL] Assignment Solution
Understanding the Example Project
Setting up and Loading Routes
Navigating with Router Links
Understanding Navigation Paths
Styling Active Router Links
Navigating Programmatically
Using Relative Paths in Programmatic Navigation
Passing Parameters to Routes
Fetching Route Parameters
Fetching Route Parameters Reactively
An Important Note about Route Observables
Passing Query Parameters and Fragments
Retrieving Query Parameters and Fragments
Practicing and some Common Gotchas
Setting up Child (Nested) Routes
Using Query Parameters - Practice
Configuring the Handling of Query Parameters
Redirecting and Wildcard Routes
Important: Redirection Path Matching
Outsourcing the Route Configuration
An Introduction to Guards
Protecting Routes with canActivate
Protecting Child (Nested) Routes with canActivateChild
Using a Fake Auth Service
Controlling Navigation with canDeactivate
Passing Static Data to a Route
Resolving Dynamic Data with the resolve Guard
Understanding Location Strategies
Planning the General Structure
Adding Navigation to the App
Fixing Page Reload Issues
Adding Child Routing Together
Configuring Route Parameters
Passing Dynamic Parameters to Links
Styling Active Recipe Items
Retrieving Route Parameters
Programmatic Navigation to the Edit Page
One Note about Route Observables
Why do we Need Angular's Help?
Template-Driven (TD) vs Reactive Approach
TD: Creating the Form and Registering the Controls
TD: Submitting and Using the Form
TD: Understanding Form State
TD: Accessing the Form with @ViewChild
TD: Adding Validation to check User Input
Built-in Validators & Using HTML5 Validation
TD: Outputting Validation Error Messages
TD: Set Default Values with ngModel Property Binding
TD: Using ngModel with Two-Way-Binding
TD: Grouping Form Controls
TD: Handling Radio Buttons
TD: Setting and Patching Form Values
Practicing Template-Driven Forms
Introduction to the Reactive Approach
Reactive: Creating a Form in Code
Reactive: Syncing HTML and Form
Reactive: Submitting the Form
Reactive: Adding Validation
Reactive: Getting Access to Controls
Reactive: Grouping Controls
Reactive: Arrays of Form Controls (FormArray)
Reactive: Creating Custom Validators
Reactive: Using Error Codes
Reactive: Creating a Custom Async Validator
Reactive: Reacting to Status or Value Changes
Reactive: Setting and Patching Values
Practicing Reactive Forms
[OPTIONAL] Assignment Solution
TD: Adding the Shopping List Form
Adding Validation to the Form
Allowing the Selection of Items in the List
Loading the Shopping List Items into the Form
Allowing the the User to Clear (Cancel) the Form
Allowing the Deletion of Shopping List Items
Creating the Template for the (Reactive) Recipe Edit Form
Creating the Form For Editing Recipes
Syncing HTML with the Form
Adding Ingredient Controls to a Form Array
Adding new Ingredient Controls
Submitting the Recipe Edit Form
Adding a Delete and Clear (Cancel) Functionality
Redirecting the User (after Deleting a Recipe)
Providing the Recipe Service Correctly
Deleting Ingredients and Some Finishing Touches
Deleting all Items in a FormArray
How Does Angular Interact With Backends?
The Anatomy of a Http Request
Using RxJS Operators to Transform Response Data
Using Types with the HttpClient
Showing a Loading Indicator
Using a Service for Http Requests
Services & Components Working Together
Using Subjects for Error Handling
Using the catchError Operator
Observing Different Types of Responses
Changing the Response Body Type
Manipulating Request Objects
Switching Between Auth Modes
Make sure you got Recipes in your backend!
Preparing the Signup Request
Sending the Signup Request
Adding a Loading Spinner & Error Handling Logic
Creating & Storing the User Data
Reflecting the Auth State in the UI
Adding the Token to Outgoing Requests
Attaching the Token with an Interceptor
Getting Started with Feature Modules
Splitting Modules Correctly
Adding Routes to Feature Modules
The ShoppingList Feature Module
Understanding Shared Modules
Understanding the Core Module
Adding an Auth Feature Module
Understanding Lazy Loading
Implementing Lazy Loading
Preloading Lazy-Loaded Code
Loading Services Differently
Starting Setup & Why We Want Standalone Components
Building a First Standalone Component
Standalone Components Are Now Stable
Standalone Directives & Connecting Building Blocks
Migrating Another Component
A Standalone Root Component
Services & Standalone Components
Routing with Standalone Components
Understanding NgRx & Its Building Blocks
Project Setup & Installing NgRx
Adding a First Reducer & Store Setup
An Alternative Way Of Creating Reducers
Reading Data From The Store
Introducing Actions & State Changing Reducers
Attaching Data To Actions
Handling Actions Without createReducer
An Alternative Way Of Defining Actions
Time To Practice: A Second Action
Installing the Effects Package
The Old @Effect Decorator & Registering Effects
Using Store Data In Effects
Analyzing the Testing Setup (as created by the CLI)
Running Tests (with the CLI)
Adding a Component and some fitting Tests
Testing Dependencies: Components and Services
Using "fakeAsync" and "tick"
Isolated vs Non-Isolated Tests
Further Resources & Where to Go Next
A Closer Look at "ng new"
Understanding the Config Files
The "angular.json" File - A Closer Look
Angular Schematics - An Introduction
Using Custom "ng generate" Schematics
Smooth Updating of Projects with "ng update"
Simplified Deployment with "ng deploy"
Understanding "Differential Loading"
Managing Multiple Projects in One Folder
Angular Libraries - An Introduction