読者です 読者をやめる 読者になる 読者になる

angular.jsでのajax通信をモジュール化して共通処理にする方法

やりたかったこと

phpとかのサーバーサイドの開発ではDBからデータを取得したり登録したりする処理をModelクラスとして定義しておきます。他の箇所からはそれを呼び出す形で開発する事が多いのですが、angular.jsでもajax通信してサーバとデータのやり取りをする部分で同じような事をしようと思ってけっこうハマりました、、、

最初は単純に$httpをつかって実装

サーバにデータを登録する処理とします。

$http({
  method: "post",
  url: "http://example.com/api/user/register",
  data: "name=" + name + "&address=" + address
}).success(function(response){
  if (response.result == 'ok') {
    //登録成功
  } else {
    //登録失敗
  }
}).error(function(reason){
  //通信エラー
});

こんな感じにControllerに直接書いていたのですが、同じ処理を別のコントローラでも必要になったのでモジュール化することにしました

モジュール化したら戻り値が取得できない!?

こんな感じで実装してみました。

モジュール

App.factory("ModelUser", function($http) {
  return {
    register: function(name, address) {
      $http({
        method: "post",
        url: "http://example.com/api/user/register",
        data: "name=" + name + "&address=" + address
      }).success(function(response){
        if (response.result == 'ok') {
          //登録成功★
          return response;
        } else {
          //登録失敗★
          return response;
        }
      }).error(function(reason){
        //通信エラー★
        return response;
      });
      //☆関数の終了場所
    }
  }
});

コントローラ(呼出し側)

var response = ModelUser.register(name, address);
console.log(response);//undefined

こうなってしまって期待通りに動きませんでした、、、
知ってる人からしたら当然なのかもしませんが、ajax通信の部分が非同期で動いているのでregisterメソッドajaxの結果が返ってくるまえに結果を返してしまうので通信の結果とか取得できないみたいです、、、※★の箇所より☆の箇所が先に実行されてしまう

モジュール化するならNgResourceを使おう

さらに調べてたらこれで上手くいきました

モジュール

App.factory("ModelUser",function($resource) {
  return $resource(
    "http://example.com/api/user/register", null, {
      regist: {
        method: "post",
      }
    }
  );
});

コントローラ(呼出し側)

ModelUser.register({
  name: name,
  address: address
}).$promise.then(function(response) {
  conosole.log(response);//ちゃんと取得できてる!!
});

ajax部分をモジュール化したければ$resourceを使うのが無難ぽいので今後これで行こうとおもいます。

以上でした