CompojureとjQueryでWebアプリを作る No.4（AjaxでのPOSTを実装）

jQueryのajaxメソッドを使ったPOSTを実装してみる。
今回はClient側（greet.html）のみの変更となる。

# jQueryライブラリを使えるようにする。
ローカルにjsファイルを持ってくるのは面倒なので、googleさんの便利なやつを使う方針で。（これについては詳細は書かない。）

greet.htmlをこんな風に変更。

```html:greet.html
<!DOCTYPE html>
<html>
  <head>
    <!-- scriptタグを追加 [ START ] -->
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">google.load("jquery", "1");</script>
    <script type="text/javascript">
      // Definition of greet function
      function greet(first_name, last_name) {
        $("#greeting_area").text("** Loading... **");
        $.ajax({
          // methodを指定。今回はPOST
          type: "post",
          // 取得後のデータの型を指定。これに従ってパースされる。
          // 現状のcompojure側の返却データの場合はtextをそのまま返しているので、
          // ここでは"text"を指定する。
          // "json"とか指定すると、パースエラーになってしまうので注意
          dataType: "text",
          // POSTデータをJSON形式で生成して送信する。
          data: {
            "first_name": first_name,
            "last_name": last_name
          },
          cache: true,
          // POST先のURLを指定。
          url: "http://localhost:3000/post_name",
          success: function (greet_message) {
            $("#greeting_area").text(greet_message);
          },
          error: function(xhr, status, err) {
            var message = "Error occured: status=" + status + ", err=" + err;
            $('#greeting_area').html(message);
          }
        });
      }
      // Initialize
      $(function(){
        // Greetボタンにクリックイベントハンドラを追加。
        $("#greet_button").click(function() {
          var first_name = $("input[name='first_name']").val();
          var last_name = $("input[name='last_name']").val();
          greet(first_name, last_name);
          // ページ遷移が発生しないよう、submitを抑制する為にfalseを返却。
          return false;
        });
      })
    </script>
    <!-- scriptタグを追加 [  END  ] -->
  </head>
  <body>
    <!-- method属性は不要 -->
    <!-- action属性はHTML5のformタグの使用的に必須なので残すが、-->
    <!-- ajaxメソッドで通信する場合は使用しない -->
    <form action="unused">
      <table>
        <tr>
          <td>First Name:</td>
          <td><input name="first_name" type="text" value="" /></td>
        </tr>
        <tr>
          <td>Last Name:</td>
          <td><input name="last_name" type="text" value="" /></td>
        </tr>
      </table>
      <div><input id="greet_button" type="submit" value="Greet" /></div>
    </form>
    <div id="greeting_area"></div><br/>
  </body>
</html>

```


# 動作確認（正常系）

ではいつものようにブラウザで次のURLへアクセス。（もし既に開いていたら`F5`キーで更新。）

![Ajax化したgreet.html](https://qiita-image-store.s3.amazonaws.com/0/39876/d3f14a39-c563-ec68-e330-4de32d55600d.png)

First Name と Last Nameに適当な名前を入力してGreetボタンをクリック。

![非同期通信して取得した挨拶文言を表示](https://qiita-image-store.s3.amazonaws.com/0/39876/ea05f36c-bcde-ecff-3604-8cc578263134.png)

Greetボタンの下に一瞬「** Loading... **」と表示された後、前回別ページに遷移した後に表示された挨拶の文言が、今度は画面遷移なしで表示された。

めでたしめでたし。


# 動作確認（異常系）

せっかくなので、`ajax`メソッドのdataTypeに"text"ではなく"json"を指定した場合にどうなるか試してみよう。

greet.htmlを次のように書き換える。（前のコメントは削除しました。）

```html:greet.html
<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">google.load("jquery", "1");</script>
    <script type="text/javascript">
      function greet(first_name, last_name) {
        $("#greeting_area").text("** Loading... **");
        $.ajax({
          type: "post",
          // 変更 [ START ] "json"を指定してみる。
          dataType: "json",
          // 変更 [  END  ]
          data: {
            "first_name": first_name,
            "last_name": last_name
          },
          cache: true,
          url: "http://localhost:3000/post_name",
          success: function (greet_message) {
            $("#greeting_area").text(greet_message);
          },
          error: function(xhr, status, err) {
            var message = "Error occured: status=" + status + ", err=" + err;
            $('#greeting_area').html(message);
          }
        });
      }
      $(function(){
        $("#greet_button").click(function() {
          var first_name = $("input[name='first_name']").val();
          var last_name = $("input[name='last_name']").val();
          greet(first_name, last_name);
          return false;
        });
      })
    </script>
  </head>
  <body>
    <form action="unused">
      <table>
        <tr>
          <td>First Name:</td>
          <td><input name="first_name" type="text" value="" /></td>
        </tr>
        <tr>
          <td>Last Name:</td>
          <td><input name="last_name" type="text" value="" /></td>
        </tr>
      </table>
      <div><input id="greet_button" type="submit" value="Greet" /></div>
    </form>
    <div id="greeting_area"></div><br/>
  </body>
</html>

```

このHTMLファイルで同じ操作を行うと、次のように表示される。

![エラー発生](https://qiita-image-store.s3.amazonaws.com/0/39876/94ea82d3-68d0-a599-1422-698ca2bdfb4b.png)

つまり、受け取ったデータをjsonとして正しくパースできなかったというエラーが発生し、エラー時のCallbackメソッドが呼び出されたということ。

というわけで、dataTypeには要注意。

が、このままではServer側から柔軟な構造のデータを返却できない。`ajax`メソッドでは是非"json"形式のデータを返したいので、次はcompojure側でどのようにすればjsonデータを返却できるのかについて触れてみよう。