Skip to content

Instantly share code, notes, and snippets.

@GregOnNet
Created May 5, 2026 10:57
Show Gist options
  • Select an option

  • Save GregOnNet/274fe7a9ab98a8366e0ae892e7a2709a to your computer and use it in GitHub Desktop.

Select an option

Save GregOnNet/274fe7a9ab98a8366e0ae892e7a2709a to your computer and use it in GitHub Desktop.
Refactoring instructions for Angular

REFACTORING.md

One File per Module

  • Ensure only one module per file (class, function, type, interface) that matches the file name
  • Extract other modules in corresponding files

S.O.L.I.D

S.O.L.I.D - UI Components

  • Review and apply S.O.L.I.D Principles to @Component
  • Detect parts that can be extracted in to simple, presentational Compoents
  • List possible Component-Refactorings
  • Ask which of them should be applied
  • Explain the benefit of extracting the respective code in an own @Component

Coding Guide Lines

Standalone Components

  • Always write standalone-Components
  • Ensure standalone: true is removed in Component-Decorator
  • Remove CommonModule only if no common directives/pipes are used
  • Prefer importing specific router directives (e.g. RouterLink) over RouterModule

Dependency Injection

AVOID

  • Constructor Injection
<!-- Example -->
  constructor(
    private route: ActivatedRoute,
    private bookApi: BookApiClient,
    private toast: ToastService
  ) {}

Prefer

  • inject
<!-- Example -->
private route = inject(ActivatedRoute),

Template Syntax

AVOID

  • Avoid directives *ngIf, *ngFor, *ngSwitch.
<!-- Example -->
<div *ngIf="state === 'loading'" class="flex justify-center items-center py-20">

Prefer

  • Avoid directives @if, @for, @switch.
<!-- Example -->
 @if(state === 'loading') {
   <div class="flex justify-center items-center py-20">
 }

Template Syntax - @for-Loops

@empty

AVOID

  • @if-statements checking for empty arrays
 @if (books.length === 0) {

PREFER

  • @empty-template of @for-loop
@for (book of books; track trackById($index, book)) {
  <app-book-item [book]="book"></app-book-item>
}
@empty {
  <!-- insert empty template here -->
}

track

PREFER

  • inline tracking instead of component function

@for (book of books; track book.id) { <app-book-item [book]="book"> } @empty {

}

property-bindings

  • Prefer signal based inputs over Decorator @Inputs
  • Prefer output over Decorator @Output

Reactivity

  • Bind Observables with toSignal to the template
  • Avoid async-Pipe

Http Errors

AVOID

  • Inline error handling since we have an HTTP-Interceptor that shows the error

ACT

  • If inline error handling is present (e.g. catchError), ASK if you should safely remove the error handling code from Code and Template
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment