add route for specific comic
This commit is contained in:
@@ -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>
|
||||
+23
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user