GraphQL+DynamoDBを使って画面にデータを出力して見た

今回の記事ではクエリ言語のGraphQLでDynamoDBに保存されたデータを実際に画面上に出力してみたいと思います.

データのインサートに関しては以前の記事で投稿しているので
[GraphQL、AppSyncを使ってDynamoDBにデータを挿入してみた](https://qiita.com/respectakagikun/items/5cbf84128c9edc5a98f3)を参照してみてください。

# 環境

* Pug を使用
* VuetifyのコンポーネントをUIで使用
* コーディング規約は Nuxt.js に則って StandardJS
* Visual Studio Code 

## Vuetifyの導入

### Vue CLI の場合

Vue CLI を使っている場合は、

```shell:shell
vue add vuetify 
```
これでVuetifyのUIコンポーネントが使用できます

### Nuxt.js の場合

Nuxt.js の場合は、Vuetify の [Quick start のドキュメント](https://vuetifyjs.com/ja/getting-started/quick-start#nuxt-install)にあるように、

```shell:shell
$ yarn add @nuxtjs/vuetify -D
# OR
$ npm install @nuxtjs/vuetify -D
```
してインストールした後、 `nuxt.config.js` の `buildModules` に

```javascript:nuxt.config.js
{
  buildModules: [
    '@nuxtjs/vuetify'
  ]
}
```
を追加してあげたらOKです。

# GraphQLを使えるようにする

AmplifyのライブラリからGraphQLのクエリをインポートし、API(GraphQL)を呼び出します。
`plugins`フォルダに、 `amplify.js`を作って、内容を以下のようにします。

```javascript:amplify.js
import Amplify, { graphqlOperation } from 'aws-amplify'
import awsConfig from '@/src/aws-exports'

Amplify.configure(awsConfig)

export default ({ app }, inject) => {
  inject('graphql', (operation, vars = {}) => Amplify.API.graphql(graphqlOperation(operation, vars)))
}
```

こうすることで、Vueコンポーネントの中から、

```javascript
this.$graphql(...)
```

で呼び出してあげることができるようになります。

# データの出力

DynamoDBに保存されているデータを出力するためのシンプルなコードを書きました。
* `default.vue`→簡易的なメインレイアウト
* `index.vue`→`Home.vue`コンポーネントを表示させる見出し
* `Home.vue`→コンポーネント。DynamoDBのデータを出力させるコードを切り出している

```vue:index.vue
<template lang="pug">
  v-layout(
    wrap
  )
    v-flex
      home
</template>

<script>
import Home from '~/components/Home'

export default {
  components: {
    Home
  },
  middleware: 'auth',
  data () {
  }
}
</script>

```

```vue:default.vue
<template lang="pug">
  v-app
    v-toolbar(color="indigo" dark fixed app)
      v-toolbar-side-icon(@click.stop="drawer = !drawer")
      v-tabs(color="indigo")
        v-tab(nuxt to="/") OVERVIEW
        v-tab(nuxt to="/signup") Customer
        v-tab(nuxt to="/signin") SIGNIN
        v-tab(nuxt to="/housekeeping") HOUSE KEEPING
        v-tab(nuxt to="/reports") REPORTS

    v-content
      nuxt

    v-footer(color="indigo" app)
      span.white--text © 2017
</template>

<script>
export default {
  data: () => ({
    drawer: false
  })
}
</script>

```

```vue:Home.vue
<template lang="pug">

    v-container

      v-layout(
        row
        wrap
      )

        v-flex(
          xs12
          sm6
          md4
          lg4
          v-for="room in rooms"
          :key="room.name"
        )
          v-card.ma-3(
            flat
            v-show="checkRoom(room)"

          )

            v-card-title
              | {{ room.number }}
              v-spacer
           
               span(
                v-if="room.guestInfo"
               ) {{ room.guestInfo.name }}

</template>

<script>
import { listUserTypes } from '@/src/graphql/queries'
export default {
  data () {
    return {
      rooms: []
    }
  },

  created () {
    this.loadUserTypes()
  },

  methods: {
    async loadUserTypes () {
      const data = await this.$graphql(listUserTypes, {
        limit: 100
      })   
    }
  }
}
</script>

```
※`UserType`はテーブルの変数名です。

今回の記事の目的はDynamoDBのデータを出力させることなので、`Home.vue`コンポーネントを中心に解説していきます。取得したいデータのテーブルは以下のようになっています

<img width="1216" alt="スクリーンショット 2019-11-26 22.15.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441587/9c93b612-38c6-4678-ae87-0f1703397b2e.png">

<img width="1012" alt="スクリーンショット 2019-11-26 22.17.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441587/b1ef9cd5-2d6b-6237-a918-8f746598d3db.png">


##出力までの手順
###1. listクエリをインポート
listクエリでデータの全てを取得したいので、`query.js`の中にある`listUserTypes`をインポートします

```javascript:script
import { listUserTypes } from '@/src/graphql/queries'
```

###2. GraphQLクエリが取得したデータを変数に代入
listクエリで取得した`UserType`テーブルのデータを`rooms`に代入します

```javascript:script

data () {
  return {
    rooms: []
  }
},

created () {
  this.loadUserTypes()
},

methods: {
  async loadUserTypes () {
    const user = await this.$graphql(listUserTypes, {
      limit: 100
    })
    this.rooms = user.data.listUserTypes.items
  }
}
```

1. `created`フックにより、インスタンスが生成された直後`loadUserTypes`メソッドを呼び出します。
2. `loadUserTypes`メソッドは`data`の中に格納されている`rooms`の空配列に対して、クエリで取得したデータを代入します

listUserで取得した中身は以下のようになっています
<img width="634" alt="スクリーンショット 2019-11-26 22.06.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441587/d21539dd-8b35-76e9-db64-00165f78d58b.png">

定数`user`から`data.listUserTypes.items`と書いてあげることで、12個のデータを`rooms`に代入することができます

### 3.出力
UIは以下のようになります。

<img width="1202" alt="スクリーンショット 2019-11-26 22.35.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441587/37d075c2-cb26-3aa0-7363-dc41b89de75b.png">


これだと見るに耐えないので少し修正を加えたいと思います。
部屋番号がランダムに並べてあるので、これを101から順に配置したいと思います。
そのために、[sortメソッド](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)を使います

`loadUserTypes`メソッドに`sort`メソッドを追加します

```javascript:methods
    async loadUserTypes () {
      const user = await this.$graphql(listUserTypes, {
        limit: 12
      })

      const result = user.data.listUserTypes.items
      result.sort(function (a, b) {
        if (a.number > b.number) {
          return 1
        } else {
          return -1
        }
      })
      this.rooms = result
    }
```

部屋番号順に並び替えることができました！

<img width="1202" alt="スクリーンショット 2019-11-26 22.36.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441587/f7ece264-89cb-2ac6-fb16-156d81877603.png">

今回は以上になります！次回は `v-card`の見栄えを以下のように、さらに良くしていきたいと思います！
<img width="1202" alt="スクリーンショット 2019-11-26 22.57.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441587/493c223d-ce53-ae48-1301-762f9763a1c4.png">