AI Skill Report Card

Building Angular Apps

B+78·Feb 3, 2026
TypeScript
// app.component.ts import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; @Component({ selector: 'app-root', template: ` <mat-toolbar color="primary"> <span>My App</span> </mat-toolbar> <div class="container"> <mat-card *ngFor="let item of items$ | async" class="item-card"> <mat-card-content>{{ item.name }}</mat-card-content> </mat-card> </div> `, styleUrls: ['./app.component.scss'] }) export class AppComponent implements OnInit { items$: Observable<any[]>; constructor(private http: HttpClient) {} ngOnInit() { this.items$ = this.http.get<any[]>('/api/items') .pipe(catchError(err => [])); } }
Recommendation
Add concrete input/output examples for the REST API calls (e.g., actual JSON request/response payloads)
  1. Set up service layer

    • Create dedicated services for each API resource
    • Use HttpClient with proper typing
    • Implement error handling with catchError
  2. Component architecture

    • Use OnPush change detection for performance
    • Leverage async pipe for subscription management
    • Keep components thin, business logic in services
  3. State management

    • Use BehaviorSubject for simple state
    • Implement loading/error states
    • Cache API responses when appropriate
  4. Styling approach

    • Use Angular Material theming
    • Create reusable SCSS mixins
    • Follow BEM methodology for custom components

Progress:

  • Create service interfaces
  • Implement HTTP services
  • Build components with Material UI
  • Add responsive SCSS
  • Handle loading/error states
Recommendation
Include a complete project structure template showing folder organization and file naming conventions

Example 1: REST Service

TypeScript
// user.service.ts @Injectable({ providedIn: 'root' }) export class UserService { private baseUrl = '/api/users'; constructor(private http: HttpClient) {} getUsers(): Observable<User[]> { return this.http.get<User[]>(this.baseUrl) .pipe( map(users => users.map(user => ({ ...user, fullName: `${user.firstName} ${user.lastName}` }))), catchError(this.handleError) ); } private handleError = (error: any): Observable<never> => { console.error('API Error:', error); return throwError(() => new Error('Something went wrong')); } }

Example 2: Material Form Component

TypeScript
// user-form.component.ts @Component({ selector: 'app-user-form', template: ` <form [formGroup]="userForm" (ngSubmit)="onSubmit()"> <mat-form-field appearance="fill"> <mat-label>Name</mat-label> <input matInput formControlName="name" required> <mat-error *ngIf="userForm.get('name')?.hasError('required')"> Name is required </mat-error> </mat-form-field> <button mat-raised-button color="primary" type="submit" [disabled]="userForm.invalid || isLoading"> <mat-spinner diameter="20" *ngIf="isLoading"></mat-spinner> {{ isLoading ? 'Saving...' : 'Save' }} </button> </form> `, changeDetection: ChangeDetectionStrategy.OnPush }) export class UserFormComponent { userForm = this.fb.group({ name: ['', Validators.required], email: ['', [Validators.required, Validators.email]] }); isLoading = false; constructor( private fb: FormBuilder, private userService: UserService, private cdr: ChangeDetectorRef ) {} onSubmit() { if (this.userForm.valid) { this.isLoading = true; this.userService.createUser(this.userForm.value) .pipe(finalize(() => { this.isLoading = false; this.cdr.markForCheck(); })) .subscribe(); } } }
Recommendation
Add specific SCSS theming examples with Material Design customization code rather than just mentioning theming
  • Use TypeScript interfaces for all API responses and form models
  • Implement OnDestroy and use takeUntil for manual subscriptions
  • Use trackBy functions in ngFor for performance
  • Leverage Angular Material CDK for complex interactions
  • Create barrel exports (index.ts) for clean imports
  • Use environment files for API URLs and configuration
  • Implement interceptors for authentication and error handling
  • Use reactive forms over template-driven forms
  • Follow Angular style guide naming conventions
  • Don't subscribe in templates - use async pipe instead
  • Don't forget to unsubscribe - leads to memory leaks
  • Don't mutate observables - use operators like map, filter
  • Don't put business logic in components - keep in services
  • Don't ignore TypeScript errors - they catch runtime issues
  • Don't skip error handling - always implement catchError
  • Don't use any type - properly type your interfaces
  • Don't forget loading states - users need feedback
  • Don't hardcode API URLs - use environment configuration
0
Grade B+AI Skill Framework
Scorecard
Criteria Breakdown
Quick Start
11/15
Workflow
11/15
Examples
15/20
Completeness
15/20
Format
11/15
Conciseness
11/15