Help us understand the problem. What is going on with this article?

Angular入門 未経験から1ヶ月でサービス作れるようにする その12. Firebaseを使ったAPI通信3

More than 1 year has passed since last update.

記事

AngularのHTTP通信のやり方を解説していきます。
FirebaseのAPIを使ってデータの更新、削除をやってみましょう。

前回の振り返り

前回は、AngularでFirebaseを用いてデータを差k末井する方法を学びました。
本記事は、Firebase周りの記事の 3記事目となりますので、過去記事の内容を頭に入れておいてください。
わからなくなったら、その1から再度やり直してみましょう。

この記事のソースコード

https://github.com/seteen/AngularGuides/tree/入門その12

Firebaseを使うようにしたことによっておかしくなっている変更部分を修正する

画面表示の修正

Firebaseを利用する前は、コード上に記載した Product のデータを利用して画面表示を行っていました。
その際には ID を 1から振っていましたが、 Firebase を利用することで、それが文字列の key に変更されました。
まずはその部分に対応します。

src/app/product/product-list/product-list.component.html
... 略
        <div class="product-line header">
          <div class="product-id">KEY</div> // <= KEY に変更
          <div class="product-name">名前</div>
          <div class="product-price">価格</div>
        </div>
        <div class="product-line" *ngFor="let product of products" (mouseenter)="hovered(product)" (mouseleave)="unhovered(product)">
          <div class="product-id">{{ product.key }} </div> // <= product.key に変更 
          <div class="product-name">{{ product.name }}</div>
          <div class="product-price">
            <span *ngIf="!product.hovered; else Unhovered">{{ product.price }}</span>
            <ng-template #Unhovered><span class="button white" [routerLink]="[product.key]">詳細</span></ng-template> // <= routerLink  product.key に変更
          </div>
        </div>
... 略

上記に伴って、少しCSSを変更しました。

001.png

上記は商品一覧画面ですが、商品詳細画面、商品編集画面も同じように修正しています。

ここまでのコミット

https://github.com/yazumoto/AngularGuides/commit/16bc8396bc2c4adf8eacaa31cf341f2c1d9241a4

データ取得部分の修正

現状では、商品詳細画面、商品編集画面では ID を基にコード上に定義したデータを検索するようにしているため、Firebaseを利用するように修正します。

src/app/shared/services/product.service.ts
... 
  get(key: string): Observable<Product> { // <= get(id: number) を修正
    return this.http.get(`${this.BASE_URL}/users/${this.UID}/products/${key}.json`, { params: { auth: this.TOKEN } }).pipe(
      map((response: any) => {
        return new Product(key, response.name, response.price, response.description);
      })
    );
  }
... 

これにより、商品詳細、商品編集画面のデータがちゃんと表示されるようになりました。

その他の小さな修正

前回商品作成画面にてデータを作成するようにしたのですが、作成後に特に画面遷移を行うようにしていなかったため、商品一覧画面に遷移するようにします。

src/app/product/product-new/product-new.component.ts
... 
  saveProduct(): void {
    if (this.productForm.valid) {
      const { name, price, description } = this.productForm.getRawValue();
      this.productService.create(new Product(null, name, price, description)).subscribe(() => {
        this.router.navigate(['/products']); // <= ここを追加
      });
    }
  }
... 

ここまでのコミット

商品作成後の遷移↓
https://github.com/yazumoto/AngularGuides/commit/5e4e38ea981845a0e9f50b2abaf3bb0e0272792a

データ取得部分の修正↓
https://github.com/yazumoto/AngularGuides/commit/173c863bc60da891540186ad506bfd7712444716

Firebaseを使ったデータの更新

次に、データの更新部分をFirebaseに対応させます。

まずは、 ProductService を更新します。

src/app/shared/services/product.service.ts
... 
  update(product: Product): Observable<void> {
    return this.http.patch(`${this.BASE_URL}/users/${this.UID}/products/${product.key}.json`, {
      name: product.name,
      price: product.price,
      description: product.description
    }, { params: { auth: this.TOKEN } }).pipe(
      map(() => {})
    );
  }
... 

httpPATCH メソッドを使うことで、データの更新ができるようになりました。
FirebaseのAPIはわかりやすくて良いですね。

呼び出し元も修正しましょう。

src/app/product/product-edit/product-edit.component.ts
... 
  saveProduct(): void {
    if (this.productForm.valid) {
      const { key, name, price, description } = this.productForm.getRawValue();
      this.productService.update(new Product(key, name, price, description)).subscribe(() => {
        this.router.navigate(['/products', this.productForm.controls.key.value]);
      });
    }
  }
... 

これで編集画面がちゃんと動作します。

ここまでのコミット

https://github.com/yazumoto/AngularGuides/commit/a3a5ef1252ef8e82f4b86a4567231809214ca68c

Firebaseを使ったデータの削除

最後に、商品の削除を実装していきます。

削除も他のAPIとほとんどやることは同じです。
httpDELETE メソッドを利用します。

ProductService への削除メソッドの実装

src/app/shared/services/product.service.ts
... 
  delete(key: string): Observable<void> {  // <= メソッドを追加
    return this.http.delete(`${this.BASE_URL}/users/${this.UID}/products/${key}.json`, { params: { auth: this.TOKEN }}).pipe(
      map(() => {})
    );
  }
... 

ほとんど更新のときと同じです。

削除ボタンの実装

現状では削除ボタンがありませんので、削除ボタンを実装していきます。

src/styles.scss
.button {
  ... 

  &.red {
    background-color: #F44336;
  }
}

削除風のボタンがなかったため、グローバルなCSSに赤いボタンを追加しておきます。

次に、編集画面に削除ボタンを追加します。

src/app/product/product-edit/product-edit.component.html
... 略
    <div class="footer">
      <span class="button white" [routerLink]="['/products', productForm.controls.key.value]">キャンセル</span>
      <button class="button black" [class.disabled]="productForm.invalid">保存</button>
      <span class="button red" (click)="deleteProduct()">削除</span> // <= 追加
    </div>
... 略

button にすると 押したときに submit イベントが発生してしまうので、キャンセルボタンと同じように span で作りました。

最後に、上記HTMLで呼ばれている deleteProduct() メソッドを追加します。

src/app/product/product-edit/product-edit.component.ts
... 
  deleteProduct(): void { // <= メソッドを追加
    if (window.confirm('本当に削除しますか?')) {
      this.productService.delete(this.productForm.controls.key.value).subscribe(() => {
        this.router.navigate(['/products']);
      });
    }
  }
... 

削除なので、 本当に削除しますか? という確認を行ってから削除するようにしました。

動作確認

データの更新、削除の動作を確認してみます。

002.gif

ここまでのコミット

https://github.com/yazumoto/AngularGuides/commit/a1cb959faca89464a5d8838791ee4f4be1ef30dc

まとめ

今回は、AngularでのFirebaseを利用するまとめとして、更新、削除を学びました。
今回で、Firebaseを使った商品の一覧、詳細、作成、編集、削除という要素が全て完成し、サービスを作れる自信がついてきたのではないでしょうか。

次回は、PIPEの使い方を見ていきます。

入門記事一覧

「Angular入門 未経験から1ヶ月でサービス作れるようにする」は、記事数が多いため、まとめ記事 を作っています。
https://qiita.com/seteen/items/43908e33e08a39612a07

seteen
Angularを広めたいエンジニア Ruby, Angularが好きです。
https://twitter.com/yazumoto
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away