Skip to main content

Overview

The LibroListComponent provides administrators with a comprehensive view of all books in the system. It displays books in a table format with options to create, edit, and delete books.

Component Metadata

@Component({
  selector: 'app-libro-list',
  standalone: true,
  imports: [CommonModule, RouterLink],
  templateUrl: './libro-list.html',
  styleUrls: ['./libro-list.css'],
})
Selector: app-libro-list Imports:
  • CommonModule - Angular common directives
  • RouterLink - Router navigation for edit links
Template: ./libro-list.html

Properties

libros

libros: Libro[] = []
Array containing all books in the system. Each book object includes:
  • id: Book identifier
  • titulo: Book title
  • portada: Cover image URL
  • anioPublicacion: Publication year
  • disponible: Availability status
  • genero: Genre object with id and name
  • autores: Array of author objects

Injected Services

private libroService = inject(LibroService)
  • LibroService - Handles all book-related API operations

Lifecycle Hooks

ngOnInit

ngOnInit(): void {
  this.cargarLibros();
}
Called when the component initializes. Immediately loads all books from the backend.

Methods

cargarLibros

cargarLibros(): void
Fetches all books from the LibroService and populates the libros array:
  • On success: Updates libros with the response data and logs to console
  • On error: Logs error message to console
This method is called on initialization and after deleting a book to refresh the list.

eliminarLibro

eliminarLibro(id: number): void
Deletes a book from the system:
  1. Displays confirmation dialog “¿Estás seguro de eliminar este libro?”
  2. If confirmed, calls LibroService.delete() with the book ID
  3. On success:
    • Reloads the book list by calling cargarLibros()
    • Shows success alert “Libro eliminado correctamente”
  4. On error:
    • Logs error to console
    • Shows error alert “No se pudo eliminar el libro.”
Parameters:
  • id - The numeric ID of the book to delete

Template Features

The component displays books in a table with the following columns:
<div class="container mt-4">
  <div class="d-flex justify-content-between align-items-center mb-3">
    <h2>Lista de Libros</h2>
    <a routerLink="/libros/nuevo" class="btn btn-primary">+ Nuevo Libro</a>
  </div>

  <table class="table table-striped table-hover">
    <thead class="table-dark">
      <tr>
        <th>ID</th>
        <th>Portada</th>
        <th>Título</th>
        <th>Año</th>
        <th>Autores</th>
        <th>Género</th>
        <th>Estado</th>
        <th class="text-end">Acciones</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let libro of libros">
        <td>{{ libro.id }}</td>
        <td>
          <img *ngIf="libro.portada" [src]="libro.portada" />
          <span *ngIf="!libro.portada">📘</span>
        </td>
        <td>{{ libro.titulo }}</td>
        <td>{{ libro.anioPublicacion }}</td>
        <td>
          <span *ngFor="let autor of libro.autores; let isLast = last">
            {{ autor.nombre }}<span *ngIf="!isLast">, </span>
          </span>
        </td>
        <td>
          <span class="badge bg-info">{{ libro.genero?.nombre }}</span>
        </td>
        <td>
          <span class="badge" [ngClass]="libro.disponible ? 'bg-success' : 'bg-danger'">
            {{ libro.disponible ? 'Disponible' : 'Agotado' }}
          </span>
        </td>
        <td class="text-end">
          <a [routerLink]="['/libros/editar', libro.id]" class="btn btn-warning btn-sm">
            ✏️ Editar
          </a>
          <button class="btn btn-danger btn-sm" (click)="eliminarLibro(libro.id)">
            🗑️ Eliminar
          </button>
        </td>
      </tr>
    </tbody>
  </table>
</div>

Full Source Code

import { Component, OnInit, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
import { LibroService } from '../../../core/services/libro';
import { Libro } from '../../../core/models/libro';

@Component({
  selector: 'app-libro-list',
  standalone: true,
  imports: [CommonModule, RouterLink],
  templateUrl: './libro-list.html',
  styleUrls: ['./libro-list.css'],
})
export class LibroListComponent implements OnInit {
  private libroService = inject(LibroService);

  libros: Libro[] = [];

  ngOnInit(): void {
    this.cargarLibros();
  }

  cargarLibros(): void {
    this.libroService.getAll().subscribe({
      next: (data) => {
        this.libros = data;
        console.log('Libros cargados:', data);
      },
      error: (err) => {
        console.error('Error al cargar libros:', err);
      },
    });
  }

  eliminarLibro(id: number): void {
    if (confirm('¿Estás seguro de eliminar este libro?')) {
      this.libroService.delete(id).subscribe({
        next: () => {
          // Recargamos la lista
          this.cargarLibros();
          alert('Libro eliminado correctamente');
        },
        error: (err) => {
          console.error('Error al eliminar:', err);
          alert('No se pudo eliminar el libro.');
        },
      });
    }
  }
}
  • Libro - Book data structure

Build docs developers (and LLMs) love