# Angular Frontend

> Angular Frontend Development - Photo Map MVP

- Skill: `diegosouzapw/angular-frontend` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add diegosouzapw/angular-frontend`
- Raw SKILL.md: https://api.skillmd.com/api/skills/diegosouzapw/angular-frontend/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: diegosouzapw (https://skillmd.com/u/diegosouzapw)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/diegosouzapw/angular-frontend

---


# Angular Frontend Development - Photo Map MVP

## Project Context

**Photo Map MVP** - Single Page Application (SPA) for managing photos with geolocation.

**Frontend Stack:**
- **Angular:** 18.2.0+ (standalone components, NO NgModules!)
- **TypeScript:** 5.5.2+ (strict mode)
- **Styling:** Tailwind CSS 3.4.17 (NOT v4 - Angular 18 incompatibility!)
- **Map:** Leaflet.js 1.9.4 + marker clustering
- **State:** RxJS 7.8.0 (BehaviorSubject pattern, no NgRx)
- **Build:** Angular CLI 18.2.0 (esbuild)

**Core Features:**
1. **Authentication:** Login/Register with JWT storage, route guards
2. **Gallery:** Responsive grid with lazy loading, rating, filtering
3. **Map View:** Leaflet integration with GPS markers, popups, clustering
4. **Admin Panel:** User management (ADMIN role only)

**Key Constraints:**
- **Standalone components ONLY** - NO NgModules anywhere!
- **Tailwind 3.4.17** - NOT 4.x (incompatibility with Angular 18)
- **inject() function** - NOT constructor injection (modern Angular 18)
- **Signals** - reactive state (Angular 16+)
- **BehaviorSubject** - service state management (no NgRx)

---

## Architecture Principles

### Standalone Components

ALL components MUST be standalone (`standalone: true`). Explicitly import dependencies in `imports` array. NO `@NgModule` anywhere.

Check: `references/angular-patterns.md` for complete patterns.

### State Management Strategy

**Decision Tree:**
- **Component-local state** → Use Signals (`signal()`, `computed()`, `effect()`)
- **Shared state (cross-component)** → Use BehaviorSubject in Services

**Pattern:** `private BehaviorSubject` → `public Observable` → Component subscribes

Check: `references/state-management.md` for detailed patterns.

### Dependency Injection

Use `inject()` function (modern Angular 18), NOT constructor injection. Make all injected services `readonly`.

Example: `private readonly photoService = inject(PhotoService);`

---

## When to Use What

### Signals vs BehaviorSubject

| Use Case | Solution |
|----------|----------|
| Component-local state (counters, UI flags, filters) | **Signals** |
| Computed values (derived state) | **Signals** (`computed()`) |
| Shared state (cross-component, services) | **BehaviorSubject** |
| Async operations (HTTP, timers) | **BehaviorSubject** |
| Complex RxJS pipelines | **BehaviorSubject** |

### Smart vs Dumb Components

| Type | Characteristics |
|------|-----------------|
| **Smart** (Container) | Inject services, manage state, business logic, fetch data |
| **Dumb** (Presentational) | NO service injection, @Input/@Output only, pure presentation |

Check: `references/component-patterns.md` for detailed examples.

---

## Implementation Workflows

### Creating Component

1. **Use checklist:** `templates/component-template.md`
2. **Standalone setup:**
   - `@Component({ standalone: true })`
   - Import dependencies: `CommonModule`, `RouterLink`, child components
3. **Dependency injection:** Use `inject()`, make services `readonly`
4. **State:** Signals for local state, BehaviorSubject consumption for shared state
5. **Template:** Use @if, @for (NOT *ngIf, *ngFor), add `data-testid` attributes
6. **Examples:**
   - Smart component → `examples/photo-gallery.component.ts`
   - Dumb component → `examples/photo-card.component.ts`

Check: `references/component-patterns.md` for Smart vs Dumb patterns.

### Creating Service

1. **Use checklist:** `templates/service-template.md`
2. **State management:**
   - Private: `private readonly itemsSubject = new BehaviorSubject<T>([])`
   - Public: `readonly items$ = itemsSubject.asObservable()`
3. **HTTP methods:** All return `Observable<T>` with explicit types
4. **Error handling:** Use `catchError`, log errors, transform to user-friendly messages
5. **Example:** `examples/photo.service.ts` (BehaviorSubject + HTTP)

Check: `references/service-patterns.md` for HTTP patterns and interceptors.

### Routing Setup

1. **Use checklist:** `templates/route-template.md`
2. **Configure routes:** `app.routes.ts` with flat Routes array
3. **Functional guards:** Use `CanActivateFn`, inject services with `inject()`
4. **Register:** `provideRouter(routes)` in `app.config.ts`
5. **Examples:**
   - Routes → `examples/app.routes.ts`
   - Guards → `examples/auth.guard.ts`

Check: `references/angular-patterns.md` for routing and guards.

### Patterns and Best Practices

- **TypeScript quality:** Check `references/typescript-quality.md` (readonly, const, strict mode)
- **RxJS patterns:** Check `references/rxjs-patterns.md` (operators, async pipe, error handling)
- **Tailwind CSS:** Check `references/tailwind-patterns.md` (utility-first, responsive, constraints)
- **Leaflet integration:** Check `references/leaflet-integration.md` (map setup, markers, clustering)
- **SOLID principles:** Check `references/solid-principles.md` (when complexity justifies it)
- **Testing:** Check `references/testing-patterns.md` (Jasmine + Karma, test IDs)
- **Responsive design:** Check `references/responsive-design.md` (mobile-first, touch-friendly)

---

## Key Reminders

**Critical Constraints:**
- ✅ ALWAYS `standalone: true` (NO NgModules!)
- ✅ Use `inject()` NOT constructor injection
- ✅ Tailwind 3.4.17 (NOT 4 - incompatibility!)
- ✅ `data-testid` on all interactive elements (kebab-case)
- ✅ `readonly` for services, `const` for variables
- ✅ Explicit return types (TypeScript strict)

**State Management:**
- ✅ Signals → component-local state
- ✅ BehaviorSubject → service state (shared)
- ✅ Async pipe in templates (automatic cleanup)

**Component Structure:**
- ✅ Smart components: inject services, manage state
- ✅ Dumb components: @Input/@Output only
- ✅ Use @if, @for, @switch (NOT *ngIf, *ngFor)

**Routing:**
- ✅ Functional guards (`CanActivateFn`)
- ✅ Return `true | false | UrlTree`
- ✅ Use `inject()` in guards

---

## Quick Reference

### Pattern Lookup

| Need | Check |
|------|-------|
| Angular patterns (standalone, control flow, inject) | `references/angular-patterns.md` |
| State management (Signals vs BehaviorSubject) | `references/state-management.md` |
| TypeScript quality (readonly, const, strict) | `references/typescript-quality.md` |
| RxJS patterns (operators, async pipe) | `references/rxjs-patterns.md` |
| Tailwind styling (utility-first, responsive) | `references/tailwind-patterns.md` |
| Leaflet maps (setup, markers, clustering) | `references/leaflet-integration.md` |
| Component patterns (Smart vs Dumb) | `references/component-patterns.md` |
| Service patterns (HTTP, BehaviorSubject) | `references/service-patterns.md` |
| SOLID principles | `references/solid-principles.md` |
| Testing (Jasmine, Karma) | `references/testing-patterns.md` |
| Responsive design (mobile-first, RWD) | `references/responsive-design.md` |

### Example Lookup

| Need | Check |
|------|-------|
| Smart component (with Signals + Services) | `examples/photo-gallery.component.ts` |
| Dumb component (@Input/@Output) | `examples/photo-card.component.ts` |
| Service (BehaviorSubject + HTTP) | `examples/photo.service.ts` |
| Filter service (state management) | `examples/filter.service.ts` |
| Map component (Leaflet integration) | `examples/map.component.ts` |
| Functional guards | `examples/auth.guard.ts` |
| Route configuration | `examples/app.routes.ts` |
| TypeScript interfaces | `examples/photo.interface.ts` |
| HTTP interceptors | `examples/jwt.interceptor.ts` |

### Template Lookup (Checklists)

| Need | Check |
|------|-------|
| Creating standalone component | `templates/component-template.md` |
| Creating service with state | `templates/service-template.md` |
| Routing + guards setup | `templates/route-template.md` |
| Writing tests (Jasmine + Karma) | `templates/test-template.md` |

