gem 'jbuilder'を使った非同期通信


日々アウトプット！

今回はgemのjbuilderを使って、非同期通信を実装しました。

# イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374908/31575d0c-eb94-6a61-f2a0-36ea36bd8ce4.png)

# 実際の画面
[![Image from Gyazo](https://i.gyazo.com/17e9c1b07a9a467cce3f4b608de2dde9.gif)](https://gyazo.com/17e9c1b07a9a467cce3f4b608de2dde9)


流れとしては、ブラウザから送信された情報をjavascriptのajaxで受け取り、
コントローラーのアクションを動かして、javascriptで受け取り再びview画面に表示です。

javascriptを使うことでページ遷移せずに表示できるようになるのすごいですよね。


# javascript での処理
今回はjQueryで記述しています。

``` user_search.js
  $('#user-search-field').on('keyup', function(){

    var input = $("#user-search-field").val();
    $.ajax({
      type: 'GET',
      url: '/users',
      data: { keyword: input },
      dataType: 'json'
    })
```

onメソッドでkeyupをトリガーにして、functionを発動させる。

## $.ajax

ajaxとは非同期にサーバーとの通信を行うこと。
有名なサービスとしては、googlemapなどがありますね。

##### 同期通信
webブラウザからサーバーにリクエストを送り、
全ての情報を受け取るので画面が真っ白になり一新される。


##### 非同期通信
一部の情報だけサーバーとやりとりして更新する。

type:はhttp通信でどういうメソッドを使うか指定する。
今回は'get'メソッドを使っています。

url:データの送り先
ターミナルでrake routesで確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374908/7fd2b744-0985-c625-475d-b71e4f22dc3d.png)

data:キーと一緒に送りたいデータを入れる。

dataType:送るデータの形式を指定しています。

# json.jbuilder

こちらの機能はRailsで用意されているgemの１種です。

```
gem 'jbuilder'
```
```terminal
$ bundle install
```


jbuilderファイルはviewsディレクトリの階下に作成します。
その際ajaxで使用しているコントローラーと同じ名前のフォルダの中に、
コントローラーのアクション名をファイルネームに使用します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374908/e1bfbb1f-5b15-1021-2970-8ffe0e77d0a3.png)


jbuilderファイルの中では、__json.KEY VALUE__ という記述の仕方をします。
こうすることによって、javascriptに値が帰ってきた際にKEYで値を呼び出すことができる。

今回のjbuilderファイルでは配列型になりように記述していますが、
配列にしないのであれば、do 〜　endの中身だけでも動きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374908/cb8b74a3-3341-7b41-c2dc-daa8e8fa08bc.png)

# javascript .done()

冒頭にありました実際の画面を実装しているjavascriptのコードの一部をご紹介します。
下記のコードは検索した名前を表示させるコードです。

``` user_search.js
  $('#user-search-field').on('keyup', function(){

    var input = $("#user-search-field").val();
    $.ajax({
      type: 'GET',
      url: '/users',
      data: { keyword: input },
      dataType: 'json'
    })
    .done(function(user_names){
      $("#user-search-result").empty();
      if (user_names.length !== 0){
        user_names.forEach(function(user_name){
          appendSearchedUserHTML(user_name);
        });
      }
      else {
        appendErrMsgToHTML("一致するユーザーが存在しません。");
      };
    })
    .fail(function(){
      alert('通信に失敗しました');
    })
  });
```

ajaxの下のdoneとfailの処理について、jbilderファイルから帰ってきた値をもとにviewにどういう動作を与えるかを書いている処理になります。
問題なく通信されれば、doneの処理が始まりますが、どこかで問題があれば、failの処理が行われます。

doneの中に定義されているfunctionの引数には帰ってきた値が含まれています。
今回はjbuilderで定義していたデータが配列型担っているので、
forEachメソッドを使って一つずつ取り出し、処理を行うように記述しています。

appendSearchedUserHtmlは自分で定義したメソッドで、
帰ってきた値を代入したHTML要素を変数に代入するメソッドを作っています。

__下記参考__

```user_search.js
  function appendSearchedUserHTML(user_name) {
    var html = `<div class="chat-group-user clearfix">
                  <p class="chat-group-user__name">${user_name.name}</p>
                  <a class="user-search-add chat-group-user__btn chat-group-user__btn--add" data-user-id="${user_name.id}" data-user-name="${user_name.name}" >追加</a>
                </div>`
    search_list.append(html);
  };
```

以上