
バックエンドからデータを取得するための準備を進めていくよ!

フロントエンドとバックエンドの連携ができるんですね!

バックエンドはいったんおいて、フロントエンドの内容を進めるよ!
前提
これまでの流れを知りたい人はこちら!
APIを呼び出す
APIについてはこちらから

まずは下ごしらえ。/shared/modelsにpain-data-log-entity.tsを作成します。
ng-pain-log/
└── pain-log/
└── src/
└── app/
├── core/
├── domain/
├── features/
├── infrastructures/
├── shared/
│ └── models/
│ └── pain-data-log-entity.ts
├── app.component.html
├── app.component.ts
├── app.component.less
└── app.routes.ts
そして、以下のようにテーブルに表示させるデータの型を作成しておきます。
export interface PainLogResultDataEntity {
id: number;
date: Date;
name: string;
movement: string;
vas: number;
memo: string;
}
次に、APIを呼び出す場所をinfrastructures以下に作成します。参考のコマンドは、
ng generate service api
です。これを実行すると、
ng-pain-log/
└── pain-log/
└── src/
└── app/
├── core/
├── domain/
├── features/
├── infrastructures/
│ └── services/
│ └── api.service.ts
├── shared/
├── app.component.html
├── app.component.ts
├── app.component.less
└── app.routes.ts
api.service.tsが作成されます。
API呼び出し先であるバックエンドは後で作成するのでお待ちくださいね!
api.service.tsは以下のような中身になります。
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { PainLogResultDataEntity } from '../../shared/models/pain-log-data-entity';
@Injectable({
providedIn: 'root'
})
export class ApiService {
private url = "http://localhost:8081"
constructor( private http: HttpClient ) { }
insertPatients(patient: PainLogResultDataEntity): Observable<PainLogResultDataEntity> {
return this.http.post<PainLogResultDataEntity>(`${this.url}/insert`, patient);
}
selectPatients(): Observable<PainLogResultDataEntity[]> {
return this.http.get<PainLogResultDataEntity[]>(`${this.url}/select`);
}
searchPatients(user: string, movement: string): Observable<PainLogResultDataEntity[]> {
return this.http.get<PainLogResultDataEntity[]>(`${this.url}/search?user=${user}&movement=${movement}`);
}
updatePatients(patient: PainLogResultDataEntity): Observable<PainLogResultDataEntity> {
return this.http.put<PainLogResultDataEntity>(`${this.url}/update`, patient);
}
deletePatients(id: number): Observable<void> {
return this.http.put<void>(`${this.url}/delete`, id);
}
}
APIの呼び出しを作成する際のキーワードとして “CRUD” とい言葉が出てきます。
・Create
・Read
・Update
・Delete
の略です。これらに関するAPIを作成することがポイントです。
CreateはInsert、ReadはSelectという言葉に代わっていますが、意味はほぼ同じです。
上記のAPIの書き方は以下を参考にしました。

これを作成したら、このapi.service.tsをどのように活用するのかを見ていきます。
ng-pain-log/
└── pain-log/
└── src/
└── app/
├── core/
├── domain/
├── features/
│ └── pages/
│ └── dashboard/
│ ├── dashboard.component.html
│ ├── dashboard.component.ts
│ └── dashboard.component.less
├── infrastructures/
├── shared/
├── app.component.html
├── app.component.ts
├── app.component.less
└── app.routes.ts
dashboard.component.tsを下記のように変更します。
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import {MatTableModule} from '@angular/material/table';
import { PainLogResultDataEntity } from '../../../shared/models/pain-log-data-entity';
import { ApiService } from '../../../infrastructures/services/api.service';
import { HttpClientModule } from '@angular/common/http';
const painLog: PainLogResultDataEntity[] = [];
@Component({
selector: 'app-dashboard',
standalone: true,
imports: [CommonModule, MatTableModule, HttpClientModule],
templateUrl: './dashboard.component.html',
styleUrl: './dashboard.component.less'
})
export class DashboardComponent {
displayedColumns: string[] = ['date', 'name', 'movement', 'vas', 'memo'];
dataSource: PainLogResultDataEntity[] = [];
constructor(private service: ApiService) {
this.service.selectPatients().subscribe(data => {
this.dataSource = data;
});
}
}
参考は以下のサイトですが、少し異なる点としてthenではなく、subscribeを利用してデータを取得しています。
dashboard.component.tsに合わせて、dashboard.componen.htmlも変更しましょう。
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<!-- Date Column -->
<ng-container matColumnDef="date">
<th mat-header-cell *matHeaderCellDef> Date </th>
<td mat-cell *matCellDef="let element"> {{element.date}} </td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<!-- Movement Column -->
<ng-container matColumnDef="movement">
<th mat-header-cell *matHeaderCellDef> Movement </th>
<td mat-cell *matCellDef="let element"> {{element.movement}} </td>
</ng-container>
<!-- VAS Column -->
<ng-container matColumnDef="vas">
<th mat-header-cell *matHeaderCellDef> VAS </th>
<td mat-cell *matCellDef="let element"> {{element.vas}} </td>
</ng-container>
<!-- Memo Column -->
<ng-container matColumnDef="memo">
<th mat-header-cell *matHeaderCellDef> Memo </th>
<td mat-cell *matCellDef="let element"> {{element.memo}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
ここまで変更して、
ng serve
または
npx ng serve --host 0.0.0.0 --poll 1
を実行してみますが、私の場合はheaderがおかしくなってしまいました。

原因を調べると、main.tsにHttpClientModuleが入っていないことのようなので、
ng-pain-log/
└── pain-log/
└── src/
├── app/
└── main.ts
import { enableProdMode, importProvidersFrom } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
import { AppComponent } from './app/app.component';
import { routes } from './app/app.routes';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { HttpClientModule } from '@angular/common/http';
bootstrapApplication(AppComponent, {
providers: [provideRouter(routes), provideAnimationsAsync(), importProvidersFrom(HttpClientModule)],
}).catch((err) => console.error(err));
上記のように直すと…

無事にweb上に表示されました!
※headerの色は変えてみました。自分で調べて変えてみてね!
次のステップ
次はバックエンドの実装に入っていきます!