Angular CLI: 16.1.5
Angular: 16.1.6
前回
の続きです。
業務で人生初のフロントエンド開発をAngularで行うことになりAngularのチュートリアルを一通り実施後、TypeScript未経験なこともありそちらの学習も兼ねて、サバイバルTypeScriptを敢えてAngularで実施しました
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CatImgComponent } from './component/cat-img/cat-img.component';
import { HttpClientModule } from "@angular/common/http";
import { CatService } from './service/catService';
@NgModule({
declarations: [
AppComponent,
CatImgComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule
],
providers: [CatService],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html
<app-cat-img></app-cat-img>
catService.ts
import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { catchError } from "rxjs/operators";
import { throwError, Observable } from "rxjs";
import { Catmodel } from "../model/catModel";
@Injectable({
providedIn: 'root'
})
export class CatService{
constructor(private http: HttpClient) {}
// The Cat APIを呼び出し猫画像URLを取得
getCatImgService(): Observable<Catmodel>{
const apiUrl = 'https://api.thecatapi.com/v1/images/search';
return this.http.get<Catmodel>(apiUrl).pipe(
catchError(error => {
console.error('画像の取得に失敗しました。', error);
return throwError('画像の取得に失敗しました。');
})
);
}
}
catModel.ts
// The Cat API呼び出し時に返ってくる値を入れる変数を定義
export class Catmodel {
id?: string;
url?: string;
width?: number;
height?: number;
}
cat-img-component.ts
import { Component, OnInit } from '@angular/core';
import { Catmodel } from 'src/app/model/catModel';
import { HttpClient } from '@angular/common/http';
import { CatService } from 'src/app/service/catService';
@Component({
selector: 'app-cat-img',
templateUrl: './cat-img.component.html',
styleUrls: ['./cat-img.component.css']
})
export class CatImgComponent implements OnInit{
catdata? : Catmodel;
error?: string;
cat?: any;
constructor(private catService: CatService, private http: HttpClient) { }
// 画面を表示した際にgetCatImgを呼び出し猫を表示する
ngOnInit() {
this.getCatImg();
}
// 更新ボタンが押された際にロード画像を表示し、getCatImgを呼び出す
onClick(){
this.catdata = undefined;
this.getCatImg();
}
// サービス側でThe Cat APIを呼び出し取得した猫画像URLをcatdataに格納
getCatImg(){
this.catService.getCatImgService().subscribe(
(data: any) => {
this.catdata = data[0];
console.log(this.catdata);
},
(error) => {
this.error = '画像の取得に失敗しました。';
}
);
}
}
cat-img-component.html
<div class="mainBodyBlock" >
<p class="titleText">サービスから猫の画像をランダムに表示</p>
<span class="Button" (click)="onClick()">更新</span>
<div class="imgBodyBlock" >
<ng-container *ngIf="catdata"; else="elseBlock">
<img [src]="catdata.url" alt="Cat" width="450px" height="300px">
</ng-container>
<ng-template #elseBlock>
<p>{{ error }}</p>
</ng-template>
</div>
</div>
cat-img-component.css
.Button {
background-color: #FF6B6B;
color: white;
padding: 1rem 2rem;
border-radius: 0.4rem;
cursor: pointer;
text-align: center;
margin: 0 auto;
display: block;
font-size: 1.2rem;
font-weight: bold;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: background-color 0.3s, transform 0.2s, box-shadow 0.3s;
}
.Button:hover {
background-color: #FF4040;
transform: scale(1.05);
box-shadow: 0 6px 10px rgba(0, 0, 0, 0.2);
}
.Button:active {
background-color: #FF4040;
transform: translateY(2px);
box-shadow: none;
}
@keyframes shake {
0% { transform: translateX(0); }
25% { transform: translateX(-5px) rotate(5deg); }
50% { transform: translateX(5px) rotate(-5deg); }
75% { transform: translateX(-5px) rotate(5deg); }
100% { transform: translateX(0); }
}
.mainBodyBlock {
width: 500px;
height: 600px;
margin: auto;
padding: 30px;
background-color: #E5E9F2;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.titleText {
text-align: center;
color: #3498DB;
font-size: 1.5rem;
font-weight: bold;
margin-bottom: 20px;
}
.imgBodyBlock {
background-color: #FFFFFF;
width: 450px;
height: 300px;
margin-top: 50px;
margin-left: auto;
margin-right: auto;
background-image: url("../../../assets/GalaxyNeko.jpg");
background-repeat: no-repeat;
background-size: cover;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.imgBodyBlock img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 10px;
}
画像が読み込まれるまではロード画面としてGalaxyNeko.jpgを表示する
.subscribe は非推奨らしいのでasyncパイプを使用する記述に変更する
cat-img-component.ts
import { Component } from '@angular/core';
import { Catmodel } from 'src/app/model/catModel';
import { CatService } from 'src/app/service/catService';
@Component({
selector: 'app-cat-img',
templateUrl: './cat-img.component.html',
styleUrls: ['./cat-img.component.css']
})
export class CatImgComponent {
catdata$!: Observable<Catmodel>;
error?: string;
constructor(private catService: CatService) { }
onClick() {
this.getCatImg();
}
getCatImg() {
this.catdata$ = this.catService.getCatImgService().pipe(
catchError(error => {
this.error = '画像の取得に失敗しました。';
return throwError("画像の取得に失敗しました。");
})
);
}
}
cat-img-component.html
<div class="mainBodyBlock">
<p class="titleText">猫の画像をランダムに表示</p>
<span class="Button" (click)="onClick()">click</span>
<div class="imgBodyBlock">
<ng-container *ngIf="catdata$ | async as catdata; else elseBlock">
<img class="catImg" [src]="catdata.url" alt="Cat">
</ng-container>
<ng-template #elseBlock>
<p>{{ error }}</p>
</ng-template>
</div>
</div>
andmore...
他にもこんな記事書いてます。