Create a List of Object Data Structures
book.service.ts
import { Injectable } from "@angular/core";
import { Book } from "./book.model";
@Injectable({
providedIn: 'root',
})
export class BookService {
getBooks(): Book[] {
return [
{
name:'I Was Caught up in a Hero Summoning, but That World Is at Peace',
author: 'Toudai, 灯台',
genre: 'Comedy, Fantasy, Harem, Romance, Slice of Life',
imageUrl: 'https://freewebnovel.com/files/article/image/1/1436/1436s.jpg',
},
{
name:'Golden Experience',
author: 'Harajun, 原純',
genre: 'Fantasy, Sci-fi, Action, Adventure',
imageUrl: 'https://freewebnovel.com/files/article/image/5/5184/5184s.jpg',
},
{
name:'Kuma Kuma Kuma Bear',
author: 'くまなの, Kumanano',
genre: 'Romance, Adventure, Fantasy, Action, Slice of Life, Comedy',
imageUrl: 'https://freewebnovel.com/files/article/image/0/559/559s.jpg',
},
{
name:'Sword, Magic and Academic Society',
author: 'Nishiura Mao, 西浦真魚',
genre: 'Action, Adventure, Comedy, Fantasy, Harem',
imageUrl: 'https://freewebnovel.com/files/article/image/4/4850/4850s.jpg',
},
{
name:'Reincarnated into a Game As the Heros Friend',
author: 'すずきゆうき, 涼樹悠樹',
genre: 'Action, Adventure, Fantasy, Romance, Shounen, Reincarnation',
imageUrl: 'https://freewebnovel.com/files/article/image/4/4156/4156s.jpg',
},
{
name:'A Demon Lords Tale: Dungeons, Monster Girls, and Heartwarming Bliss',
author: 'Ryuryu',
genre: 'Shounen, Seinen, Fantasy, Comedy, Harem, Slice of Life, Action, Romance, Adventure',
imageUrl: 'https://freewebnovel.com/files/article/image/0/752/752s.jpg',
},
{
name:'The Hero King, Reincarnate to Master the Art of War ~And Thus, I Became The Strongest Knight Disciple (♀) in The World~',
author: 'Hayaken',
genre: 'Action, Adventure, Comedy, Fantasy, Gender bender',
imageUrl: 'https://freewebnovel.com/files/article/image/3/3107/3107s.jpg',
},
];
}
}
book.model.ts
export interface Book {
name: string;
author: string;
genre: string;
imageUrl: string;
}
book.component.ts
import { CommonModule, } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { BookService } from './book.service';
@Component({
selector: 'app-book',
standalone: true,
imports: [CommonModule],
providers: [BookService],
templateUrl: './book.component.html',
styleUrl: './book.component.css'
})
export class BookComponent implements OnInit {
books: any[] = [];
constructor(private booksService: BookService) {}
ngOnInit(): void {
this.books = this.booksService.getBooks();
}
}
book.component.html
<div class="book-grid">
<div class="book-card" *ngFor="let book of books">
<img
class="book-card__image"
[src]="book.imageUrl"
[alt]="book.name"
onerror="this.src='assets/images/placeholder.jpg';"
/>
<div class="book-card__badges">
</div>
<h3 class="book-card__title">{{ book.name }}</h3>
<p class="book-card__author">Author: {{ book.author }}</p>
<p class="book-card__genre">Genre: {{ book.genre }}</p>
<div class="book-card__buttons">
<button class="button button--primary">Read</button>
</div>
</div>
</div>
Output
Mobile
Tablet
PC
Firebase link: https://amador-library-grid.web.app
Git repo link: https://github.com/kaysie0919/Angular-Library-Grid.git