|
@@ -24,7 +24,7 @@
|
|
| 24 |
aria-label="Search"
|
| 25 |
/>
|
| 26 |
|
| 27 |
-
@for (b of
|
| 28 |
<app-book-card [book]="b" (like)="addLikedBook($event)" />
|
| 29 |
}
|
| 30 |
</div>
|
|
|
|
| 24 |
aria-label="Search"
|
| 25 |
/>
|
| 26 |
|
| 27 |
+
@for (b of books.value(); track b.isbn) {
|
| 28 |
<app-book-card [book]="b" (like)="addLikedBook($event)" />
|
| 29 |
}
|
| 30 |
</div>
|
|
@@ -1,5 +1,6 @@
|
|
| 1 |
-
import { Component,
|
| 2 |
import { Field, form } from '@angular/forms/signals';
|
|
|
|
| 3 |
|
| 4 |
import { Book } from '../../shared/book';
|
| 5 |
import { BookCard } from '../book-card/book-card';
|
|
@@ -13,25 +14,24 @@ import { BookStore } from '../../shared/book-store';
|
|
| 13 |
})
|
| 14 |
export class BooksOverviewPage {
|
| 15 |
#bookStore = inject(BookStore);
|
|
|
|
| 16 |
|
| 17 |
-
|
|
|
|
| 18 |
protected searchField = form(this.searchTerm);
|
| 19 |
|
| 20 |
-
protected books = this.#bookStore.getAll();
|
| 21 |
protected likedBooks = signal<Book[]>([]);
|
| 22 |
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
}
|
| 31 |
-
|
| 32 |
-
const term = this.searchTerm().toLowerCase();
|
| 33 |
-
return this.books.value().filter((b) => b.title.toLowerCase().includes(term));
|
| 34 |
-
});
|
| 35 |
|
| 36 |
addLikedBook(newLikedBook: Book) {
|
| 37 |
const foundBook = this.likedBooks().find(
|
|
|
|
| 1 |
+
import { Component, effect, inject, input, linkedSignal, signal } from '@angular/core';
|
| 2 |
import { Field, form } from '@angular/forms/signals';
|
| 3 |
+
import { Router } from '@angular/router';
|
| 4 |
|
| 5 |
import { Book } from '../../shared/book';
|
| 6 |
import { BookCard } from '../book-card/book-card';
|
|
|
|
| 14 |
})
|
| 15 |
export class BooksOverviewPage {
|
| 16 |
#bookStore = inject(BookStore);
|
| 17 |
+
#router = inject(Router);
|
| 18 |
|
| 19 |
+
readonly search = input<string>();
|
| 20 |
+
protected searchTerm = linkedSignal(() => this.search() || '');
|
| 21 |
protected searchField = form(this.searchTerm);
|
| 22 |
|
| 23 |
+
protected books = this.#bookStore.getAll(this.searchTerm);
|
| 24 |
protected likedBooks = signal<Book[]>([]);
|
| 25 |
|
| 26 |
+
constructor() {
|
| 27 |
+
effect(() => {
|
| 28 |
+
this.#router.navigate([], {
|
| 29 |
+
queryParams: {
|
| 30 |
+
search: this.searchTerm() || null
|
| 31 |
+
}
|
| 32 |
+
});
|
| 33 |
+
});
|
| 34 |
+
}
|
|
|
|
|
|
|
|
|
|
| 35 |
|
| 36 |
addLikedBook(newLikedBook: Book) {
|
| 37 |
const foundBook = this.likedBooks().find(
|
|
@@ -11,9 +11,12 @@ export class BookStore {
|
|
| 11 |
#http = inject(HttpClient);
|
| 12 |
#apiUrl = 'https://api6.angular-buch.com';
|
| 13 |
|
| 14 |
-
getAll(): HttpResourceRef<Book[]> {
|
| 15 |
return httpResource<Book[]>(
|
| 16 |
-
() =>
|
|
|
|
|
|
|
|
|
|
| 17 |
{ defaultValue: [] }
|
| 18 |
);
|
| 19 |
}
|
|
|
|
| 11 |
#http = inject(HttpClient);
|
| 12 |
#apiUrl = 'https://api6.angular-buch.com';
|
| 13 |
|
| 14 |
+
getAll(searchTerm: Signal<string>): HttpResourceRef<Book[]> {
|
| 15 |
return httpResource<Book[]>(
|
| 16 |
+
() => ({
|
| 17 |
+
url: `${this.#apiUrl}/books`,
|
| 18 |
+
params: { filter: searchTerm() }
|
| 19 |
+
}),
|
| 20 |
{ defaultValue: [] }
|
| 21 |
);
|
| 22 |
}
|