【Ionic+Firebaseでアプリ開発】お気に入り登録機能を実装する

#はじめに
[【Ionic+Firebaseでアプリ開発】Firestoreの中身を一覧表示する](https://qiita.com/se_fy/items/c5f832629957fc69d910)の続きです。
今回はFirestoreの中身を一覧表示するだけのiOSアプリに、お気に入り登録機能を追加します。

以下のように実装します。
・追加したいアイテムを左から右にスライドすると、登録ボタンが現れ、タップするとお気に入りに登録できる
・「お気に入りに登録しました」と表示する([ion-toast](https://ionicframework.com/docs/api/toast))
・[ion-item-slidingでタップした際にスライドを閉じる](https://qiita.com/se_fy/items/9a03354ec0223b7116fc)
・お気に入りに登録したアイテムはお気に入り一覧画面に表示される
・お気に入り一覧画面から削除したい場合はアイテムを右から左にスライドすると、削除ボタンが現れ、タップすると削除できる
![firebaseList.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410068/d4f9ad44-1793-1948-35d3-5bac9ae298c4.gif)

#お気に入りアイテムを一覧表示するページを実装する
1.お気に入り一覧表示ページを生成する

```
$ ionic g page favoriteList
```

2.お気に入り一覧表示ページを作成する

```app/favorite-list/favorite-list.page.html
<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-back-button text="戻る" defaultHref="home"></ion-back-button>
    </ion-buttons>
    <ion-title>お気に入り</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content fullscreen>
  <ion-card *ngFor="let favorite of favoriteList; let i = index" class="activated">
    <ion-item-sliding >
      <ion-item-options side="end">
        <ion-item-option (click)="deleteFavorite(i)" color="danger">削除</ion-item-option>
      </ion-item-options>
      <ion-item (click)="openPage(favorite.url)" class="activated">
      <ion-card-header>
        <ion-img src = "{{favorite.image}}" class="image"></ion-img>
      </ion-card-header>
        <ion-card-content>
            <p><font size="2">レベル：{{ favorite.level }}</font></p><br>
            <p><font size="4" color="#000000">{{ favorite.name }}</font></p>
        </ion-card-content>
      </ion-item>
    </ion-item-sliding>
  </ion-card>
</ion-content>
```

3.お気に入り一覧表示ページの処理を実装する

```app/home/favorite-list.page.ts
import { Component} from '@angular/core';
import { Router, ActivatedRoute, NavigationExtras} from '@angular/router';

@Component({
  selector: 'app-favorite-list',
  templateUrl: './favorite-list.page.html',
  styleUrls: ['./favorite-list.page.scss'],
})
export class FavoriteListPage {
  favoriteList = [];
  constructor(
    private activatedRoute: ActivatedRoute,
    private router: Router,
  ) {
    this.activatedRoute.queryParams.subscribe(params => {
      this.favoriteList = JSON.parse(params.favoriteList);
    });
  }

  deleteFavorite(i) {
    this.favoriteList.splice(i,1);
  }

  back(){
    const navigationExtras: NavigationExtras = {
      queryParams:{
        favoriteList: JSON.stringify(this.favoriteList),
      }
    };
    this.router.navigate(['home'], navigationExtras);
  }
}
```

#一覧表示ページにお気に入り登録機能を実装する
1.一覧表示ページにお気に入り登録のUIを追加する

```app/home/home.page.ts
<ion-header [translucent]="true">
  <ion-toolbar>
    <ion-title>
      記事一覧
    </ion-title>
    <ion-button (click)="presentFavorite()" slot="end">
      <ion-icon name="star-outline"></ion-icon>
    </ion-button>
  </ion-toolbar>
</ion-header>

<ion-content [fullscreen]="true">
  <ion-card *ngFor="let trick of groundtricks" class="activated">
    <ion-item-sliding #slidingItem>
      <ion-item (click)="openPage(trick.url)" class="activated">
        <ion-card-header>
          <ion-img src = "{{trick.image}}" class="image"></ion-img>
        </ion-card-header>
        <ion-card-content>
          <p><font size="2">レベル：{{ trick.level }}</font></p><br>
          <p><font size="3" color="#000000">{{ trick.name }}</font></p>
        </ion-card-content>
      </ion-item>
      <ion-item-options side="start">
        <ion-item-option (click)="favorite(trick); slidingItem.close()"><ion-icon size="large" name="star-outline"></ion-icon></ion-item-option>
      </ion-item-options>
    </ion-item-sliding>
  </ion-card>
</ion-content>

```

2.一覧表示ページにお気に入り登録の処理を追加する

```app/home/home.page.ts
import { Component, OnInit} from '@angular/core';
import { Router, NavigationExtras } from '@angular/router';
import { AngularFirestore } from '@angular/fire/firestore';
import { InAppBrowser } from '@ionic-native/in-app-browser/ngx';
import { ToastController} from '@ionic/angular';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage implements OnInit{
  groundtricks = [];
  favoriteList = [];

  constructor(
    private firestore: AngularFirestore,
    private inAppBrowser: InAppBrowser,
    public toastController: ToastController,
    private router: Router,
  ) {}

  ngOnInit() {
    this.readGroundtrick().subscribe(data => {
      this.groundtricks = data.map(e => {
        return {
          genre: e.payload.doc.data()['genre'],
          image: e.payload.doc.data()['image'],
          level: e.payload.doc.data()['level'],
          rotation: e.payload.doc.data()['rotation'],
          name: e.payload.doc.data()['name'],
          url: e.payload.doc.data()['url'],
        };
      });
    });
  }

  async favorite(item) {
    const toast = await this.toastController.create({
      color: 'dark',
      duration: 2000,
      message: 'お気に入りに登録しました。'
    });
    await toast.present();
    this.favoriteList.push(item);
  } 

  presentFavorite(){
    const navigationExtras: NavigationExtras = {
      queryParams:{
        favoriteList: JSON.stringify(this.favoriteList),
      }
    };
    this.router.navigate(['favorite-list'], navigationExtras);
  }

  openPage(url){
    this.inAppBrowser.create(url);
  }

  readGroundtrick() {
    return this.firestore.collection('groundtrick').snapshotChanges();
  }
}
```

#おわりに
今回は、一覧表示するページにお気に入り登録機能を実装しました。
しかし、今回の実装ではアプリを再起動するとお気に入り登録したアイテムが消えてしまいます。
次回は再起動しても消えないようにする実装を紹介します。
[【Ionic+Firebaseでアプリ開発】 データの永続化](https://qiita.com/se_fy/items/cebb1eb0cc6ebdaf4ad7)(2020/6/11追記)