add route for specific comic

This commit is contained in:
Thomas Peetz
2025-09-19 00:55:04 +02:00
parent 21533ee9f9
commit 63ac0231dc
13 changed files with 157 additions and 5 deletions
@@ -0,0 +1,7 @@
<p>comic-comic works!</p>
<p>comic works!</p>
<div>
<a [routerLink]="['/', 'comic', 'comics', comic().id]" routerLinkActive="active">
<span>{{ comic().title }}</span>
</a>
</div>
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ComicComicComponent } from './comic-comic.component';
describe('ComicComicComponent', () => {
let component: ComicComicComponent;
let fixture: ComponentFixture<ComicComicComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ComicComicComponent]
})
.compileComponents();
fixture = TestBed.createComponent(ComicComicComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,13 @@
import { Component, input } from '@angular/core';
import { Comic } from '../comic-comics/comic.model';
import { RouterLink, RouterLinkActive } from '@angular/router';
@Component({
selector: 'app-comic-comic',
imports: [RouterLink, RouterLinkActive],
templateUrl: './comic-comic.component.html',
styleUrl: './comic-comic.component.css'
})
export class ComicComicComponent {
comic = input.required<Comic>();
}
@@ -0,0 +1,9 @@
<p>comic-comics-list works!</p>
<p>comic-list works!</p>
<ul>
@for (comic of comics(); track comic.id) {
<li>
<app-comic-comic [comic]="comic"/>
</li>
}
</ul>
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ComicComicsListComponent } from './comic-comics-list.component';
describe('ComicComicsListComponent', () => {
let component: ComicComicsListComponent;
let fixture: ComponentFixture<ComicComicsListComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ComicComicsListComponent]
})
.compileComponents();
fixture = TestBed.createComponent(ComicComicsListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,37 @@
import { Component, DestroyRef, inject, OnInit, signal } from '@angular/core';
import { Comic } from '../comic-comics/comic.model';
import { ComicService } from '../comic-comics/comic.service';
import { ComicComicComponent } from "../comic-comic/comic-comic.component";
@Component({
selector: 'app-comic-comics-list',
imports: [ComicComicComponent],
templateUrl: './comic-comics-list.component.html',
styleUrl: './comic-comics-list.component.css'
})
export class ComicComicsListComponent implements OnInit {
comics = signal<Comic[] | undefined>(undefined);
isFetching = signal(false);
error = signal('');
private comicsService = inject(ComicService);
private destroyRef = inject(DestroyRef);
ngOnInit() {
this.isFetching.set(true);
const subscription = this.comicsService.loadComics().subscribe({
next: (comics) => {
this.comics.set(comics);
},
error: (error: Error) => {
this.error.set(error.message);
},
complete: () => {
this.isFetching.set(false);
}
});
this.destroyRef.onDestroy(() => {
subscription.unsubscribe();
})
}
}
@@ -1 +1,7 @@
<p>comic-comics works!</p>
<div>
<app-comic-comics-list/>
</div>
<div>
<h2>Comic Details</h2>
</div>
@@ -1,8 +1,9 @@
import { Component } from '@angular/core';
import { ComicComicsListComponent } from "../comic-comics-list/comic-comics-list.component";
@Component({
selector: 'app-comic-comics',
imports: [],
imports: [ComicComicsListComponent],
templateUrl: './comic-comics.component.html',
styleUrl: './comic-comics.component.css'
})
@@ -0,0 +1,5 @@
export interface Comic {
id: string;
title: string;
completed: boolean;
}
@@ -0,0 +1,28 @@
import { HttpClient } from "@angular/common/http";
import { inject, Injectable, signal } from "@angular/core";
import { Comic } from "./comic.model";
import { catchError, map, throwError } from "rxjs";
@Injectable({
providedIn: 'root'
})
export class ComicService {
private httpClient = inject(HttpClient);
private comics = signal<Comic[]>([]);
loadedComics = this.comics.asReadonly();
loadComics() {
return this.fetchComics('http://127.0.0.1:8800/api/comics/comics', 'Someting went wrong fetching comics. Please try again later.');
}
private fetchComics(url: string, errorMessage: string) {
return this.httpClient.get<Comic[]>(url).pipe(
map((resData) => resData),
catchError((error) => {
console.log(error);
return throwError(() => new Error(errorMessage));
})
);
}
}
@@ -8,10 +8,10 @@ export const comicRoutes: Routes = [
path: 'comics',
component: ComicComicsComponent
},
// {
// path: 'comics/:comicId',
// component: ComicDetailsComponent,
// },
{
path: 'comics/:comicId',
component: ComicComicsComponent,
},
{
path: 'publisher',
component: ComicPublishersComponent