Skip to main content

Overview

The LibroService provides methods to create, read, update, and delete books in the Biblioteca Virtual system. It handles all HTTP communications with the backend /libros endpoint. Location: src/app/core/services/libro.ts

Constructor

private http = inject(HttpClient);
Uses Angular’s inject() function to obtain HttpClient instance.

Properties

apiUrl
string
default:"${environment.apiUrl}/libros"
Base URL for libro endpoints, configured from environment settings.

Methods

getAll()

Retrieves all books from the library.
getAll(): Observable<Libro[]>
Returns: Observable<Libro[]> - Array of all books
Libro[]
array
Array of book objects
id
number
Unique book identifier
titulo
string
Book title
portada
string
URL to the book cover image
anioPublicacion
number
Year of publication
disponible
boolean
Whether the book is available for borrowing
genero
Genero
Book’s genre (id and nombre)
autores
Autor[]
Array of authors (id, nombre, urlFoto)
Example:
this.libroService.getAll().subscribe({
  next: (libros) => {
    console.log(`Found ${libros.length} books`);
    this.books = libros;
  },
  error: (error) => {
    console.error('Error fetching books:', error);
  }
});
API Endpoint: GET ${apiUrl}

getById()

Retrieves a specific book by its ID.
getById(id: number): Observable<Libro>
id
number
required
The unique identifier of the book to retrieve
Returns: Observable<Libro> - Single book object Example:
const libroId = 42;

this.libroService.getById(libroId).subscribe({
  next: (libro) => {
    console.log('Book details:', libro.titulo);
    this.selectedBook = libro;
  },
  error: (error) => {
    console.error('Book not found:', error);
  }
});
API Endpoint: GET ${apiUrl}/{id} Use Case: Loading book data for editing forms

create()

Creates a new book in the library.
create(libro: any): Observable<Libro>
libro
object
required
Book data to create. Must include genero and autores.Required Properties:
  • titulo (string): Book title
  • disponible (boolean): Availability status
  • genero (Genero): Genre object with id and nombre
  • autores (Autor[]): Array of author objects
Optional Properties:
  • portada (string): Cover image URL
  • anioPublicacion (number): Publication year
Returns: Observable<Libro> - The created book with server-assigned ID Example:
const newBook = {
  titulo: 'Cien años de soledad',
  portada: 'https://example.com/cover.jpg',
  anioPublicacion: 1967,
  disponible: true,
  genero: {
    id: 1,
    nombre: 'Realismo Mágico'
  },
  autores: [
    {
      id: 5,
      nombre: 'Gabriel García Márquez',
      urlFoto: 'https://example.com/gabo.jpg'
    }
  ]
};

this.libroService.create(newBook).subscribe({
  next: (createdLibro) => {
    console.log('Book created with ID:', createdLibro.id);
    this.router.navigate(['/libros']);
  },
  error: (error) => {
    console.error('Error creating book:', error);
  }
});
API Endpoint: POST ${apiUrl}

update()

Updates an existing book.
update(id: number, libro: any): Observable<Libro>
id
number
required
The ID of the book to update
libro
object
required
Updated book data. Should include all required fields (titulo, disponible, genero, autores)
Returns: Observable<Libro> - The updated book object Example:
const updatedBook = {
  titulo: 'Cien años de soledad (Edición Especial)',
  portada: 'https://example.com/new-cover.jpg',
  anioPublicacion: 1967,
  disponible: false, // Currently borrowed
  genero: { id: 1, nombre: 'Realismo Mágico' },
  autores: [{ id: 5, nombre: 'Gabriel García Márquez' }]
};

this.libroService.update(42, updatedBook).subscribe({
  next: (libro) => {
    console.log('Book updated successfully');
    this.loadBooks();
  },
  error: (error) => {
    console.error('Error updating book:', error);
  }
});
API Endpoint: PUT ${apiUrl}/{id}

delete()

Deletes a book from the library.
delete(id: number): Observable<any>
id
number
required
The ID of the book to delete
Returns: Observable<any> - Plain text response from server Response Type: Text (uses responseType: 'text' to handle empty or plain text responses) Example:
const libroId = 42;

if (confirm('¿Está seguro de eliminar este libro?')) {
  this.libroService.delete(libroId).subscribe({
    next: (response) => {
      console.log('Delete response:', response);
      this.loadBooks(); // Refresh the list
    },
    error: (error) => {
      console.error('Error deleting book:', error);
    }
  });
}
API Endpoint: DELETE ${apiUrl}/{id}

Complete CRUD Example

Example component using all LibroService methods:
import { Component, OnInit, inject } from '@angular/core';
import { LibroService } from '../core/services/libro';
import { Libro } from '../core/models/libro';

@Component({
  selector: 'app-libro-list',
  templateUrl: './libro-list.html'
})
export class LibroListComponent implements OnInit {
  libroService = inject(LibroService);
  libros: Libro[] = [];

  ngOnInit() {
    this.loadLibros();
  }

  loadLibros() {
    this.libroService.getAll().subscribe({
      next: (data) => {
        this.libros = data;
      },
      error: (err) => console.error(err)
    });
  }

  editLibro(id: number) {
    this.libroService.getById(id).subscribe({
      next: (libro) => {
        // Load into edit form
        this.openEditForm(libro);
      }
    });
  }

  deleteLibro(id: number) {
    this.libroService.delete(id).subscribe({
      next: () => {
        this.loadLibros();
      }
    });
  }
}

Data Models

Libro Interface

interface Libro {
  id: number;
  titulo: string;
  portada?: string;
  anioPublicacion?: number;
  disponible: boolean;
  genero: Genero;
  autores: Autor[];
}
interface Genero {
  id: number;
  nombre: string;
}

interface Autor {
  id: number;
  nombre: string;
  urlFoto?: string;
}

Error Handling

All methods return Observables that may emit errors:
this.libroService.getAll().subscribe({
  next: (libros) => { /* success */ },
  error: (error) => {
    if (error.status === 404) {
      console.error('Book not found');
    } else if (error.status === 403) {
      console.error('Access forbidden');
    } else {
      console.error('Unexpected error:', error);
    }
  }
});

See Also

Build docs developers (and LLMs) love