Skip to main content

Overview

The Empty State component displays a friendly message and image when no data is available. It’s used in the favorites page when the user has no saved items or when search/filter results are empty. Location: src/app/shared/components/empty-state/empty-state.component.ts

Key Features

  • Customizable Message: Override default “no results” text
  • Customizable Image: Provide custom illustration URL
  • Accessible: Includes alt text for images
  • Default Styling: Pre-configured with friendly defaults

Component Structure

@Component({
  selector: 'app-empty-state',
  templateUrl: './empty-state.component.html',
  styleUrls: ['./empty-state.component.scss']
})
export class EmptyStateComponent {
  @Input() message = "Upps..We didn't find anything...";
  @Input() imageUrl = "/assets/images/monkey3.jpg";
  @Input() alt = 'empty state image';
}

Input Properties

message
string
default:"Upps..We didn't find anything..."
The message displayed to the user when there’s no data. Can be customized for different contexts.
imageUrl
string
default:"/assets/images/monkey3.jpg"
URL of the image to display. Defaults to a friendly monkey illustration.
alt
string
default:"empty state image"
Alt text for the image for accessibility.

Usage

Basic Usage (Default)

<app-empty-state></app-empty-state>
Displays:
  • Message: “Upps..We didn’t find anything…”
  • Image: Default monkey illustration

Custom Message

<app-empty-state 
  message="No favorites yet! Start adding some movies.">
</app-empty-state>

Custom Message and Image

<app-empty-state 
  message="No search results found. Try different keywords."
  imageUrl="/assets/images/no-results.png"
  alt="No results illustration">
</app-empty-state>

In Favorites Page

<div class="all-favorites-card">
  <ng-container *ngFor="let item of favorites; trackBy : trackByFn">
    <app-favorites-card [item]="item"></app-favorites-card>
  </ng-container>
  
  <ng-container *ngIf="favorites.length === 0 && !isRevalidatingAfterDelete">
    <app-empty-state></app-empty-state>
  </ng-container>
</div>

Template Structure

<h1>{{ message }}</h1>
<div class="img-container">
  <img [src]="imageUrl" [alt]="alt" />
</div>

Use Cases

1. No Favorites

<app-empty-state 
  message="Your favorites collection is empty. Start exploring!">
</app-empty-state>

2. Empty Search Results

<app-empty-state 
  message="No movies match your search criteria.">
</app-empty-state>

3. Empty Filter Results

<app-empty-state 
  message="No items match the selected filters.">
</app-empty-state>

4. No Data After Delete

// In favorites component
if (this.favorites.length === 0 && !this.isRevalidatingAfterDelete) {
  // Show empty state
}

Conditional Display

Always wrap the empty state in a conditional to only show when appropriate:
<!-- Good: Shows only when array is empty -->
<ng-container *ngIf="items.length === 0">
  <app-empty-state></app-empty-state>
</ng-container>

<!-- Good: Shows after filtering -->
<ng-container *ngIf="filteredItems.length === 0 && !isLoading">
  <app-empty-state message="No results found for your search."></app-empty-state>
</ng-container>

<!-- Bad: Always shows -->
<app-empty-state></app-empty-state>

Styling

The component uses scoped styles in empty-state.component.scss:
:host {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  text-align: center;
}

h1 {
  font-size: 1.5rem;
  color: var(--text-secondary);
  margin-bottom: 2rem;
}

.img-container {
  max-width: 400px;
  
  img {
    width: 100%;
    height: auto;
  }
}

Best Practices

1. Provide Context

Make the message specific to the situation:
<!-- Good: Specific -->
<app-empty-state message="No movies in your watchlist yet."></app-empty-state>

<!-- Bad: Generic -->
<app-empty-state message="Empty."></app-empty-state>

2. Wait for Loading

Don’t show empty state while data is loading:
<ng-container *ngIf="isLoading">
  <app-loading-spinner [visible]="true"></app-loading-spinner>
</ng-container>

<ng-container *ngIf="!isLoading && items.length === 0">
  <app-empty-state></app-empty-state>
</ng-container>

3. Provide Next Steps

Consider adding action buttons below the empty state:
<app-empty-state message="Your favorites list is empty."></app-empty-state>
<button mat-raised-button color="primary" routerLink="/">
  Browse Movies
</button>

4. Use Appropriate Images

Choose images that match the context:
  • No favorites: Heart or bookmark illustration
  • No search results: Magnifying glass
  • No data: Empty box or folder
  • Error state: Warning icon

Accessibility

Ensure the empty state is accessible:
<div role="status" aria-live="polite">
  <app-empty-state 
    message="No results found"
    alt="Illustration of empty search results">
  </app-empty-state>
</div>

Common Patterns

With Loading State

export class FavoritesComponent {
  favorites: MediaItem[] = [];
  isLoading = false;
  
  ngOnInit(): void {
    this.isLoading = true;
    this.loadFavorites();
  }
}
<app-loading-spinner [visible]="isLoading"></app-loading-spinner>

<ng-container *ngIf="!isLoading">
  <div class="items-container" *ngIf="favorites.length > 0">
    <!-- Display items -->
  </div>
  
  <app-empty-state *ngIf="favorites.length === 0"></app-empty-state>
</ng-container>

With Filters

get hasActiveFilters(): boolean {
  return this.searchParams.mediaType || this.searchParams.searchTerm;
}
<app-empty-state 
  *ngIf="filteredItems.length === 0"
  [message]="hasActiveFilters ? 'No items match your filters.' : 'Your collection is empty.'">
</app-empty-state>

Build docs developers (and LLMs) love