Как использовать transformRequest и transformResponse для изменения данных для $resource?

Я использую API JSONAPI, и один из требований к формату состоит в том, что все данные (входящие и исходящие) должны быть завернутый в объект data. Поэтому мой запрос выглядит так:

{
  "data": {
    "email": "[email protected]",
    "password": "pass",
    "type": "sessions"
  }
}

И мой ответ выглядит так:

{
  "data": {
    "user_id": 13,
    "expires": 7200,
    "token": "gpKkNpSIzxrkYbQiYxc6us0yDeqRPNRb9Lo1YRMocyXnXbcwXlyedjPZi88yft3y"
  }
}

В моем контроллере при создании нового запроса сеанса я:

$scope.signin = ->
  session = new Session
    email: $scope.user.email
    password: $scope.user.password

  session.$save()

  console.log session
  console.log session.token
  if not session.token
    alert 'Invalid Login'
  else
    $rootScope.session_token = session.token
    $state.go 'app.dashboard'

И мой Session - это factory, который выглядит так:

angular.module('webapp').factory 'Session', [
  '$resource'
  ($resource) ->
    $resource 'http://localhost:9500/v1/sessions',
      id: '@id'
    ,
      save:
        method: 'POST'
        transformRequest: (data) ->
          result =
            data: JSON.parse JSON.stringify data
          result.data.types = 'sessions'
          result = JSON.stringify result
          result
        transformResponse: (data) ->
          result = JSON.parse data
          a = JSON.parse JSON.stringify result.data
          console.log a
          a

Запрос в порядке. Кажется, что форматирование и синтаксический анализ работают. Однако ответ, когда я log отображается как Resource, а не Object. И session.token отображается как undefined, хотя сервер возвращает достоверные данные.

Как мне изменить свой transformResponse для этого?

Ответы

Ответ 1

Я думаю, что вы хотите захватить свой ресурсный ответ обещанием:

session.$save().$promise.then(function (result) {
    console.log (result);
});

Ответ 2

Могу ли я предложить XHR-перехватчик?

xhrInterceptor.js

(function (app) {
    "use strict";

    function XhrInterceptor($q) {
        return {

            request: function requestInterceptor(config) {
                var data = config.data;

                if (data &&
                    config.method === "POST") {

                    config.data = {
                        data: data
                    };
                }

                return config || $q.when(config);
            },

            response: function responseInterceptor(response) {
                if (typeof response === "object") {
                    if (response.config.method === "POST") {
                        response.data = response.data.data || {};
                    }
                }

                return response || $q.when(response);
            }
        };
    }

    app
        .factory("app.XhrInterceptor", ["$q", XhrInterceptor]);

})(window.app);

app.js

В случае вашей фазы конфигурации или другой логики инициализации добавьте ответный перехватчик.

app
    .config(["$httpProvider", function ($httpProvider) {
            $httpProvider.interceptors.push("app.XhrInterceptor");
    });

Дополнительная информация

XHR Interceptor в веб-приложении AngularJS

Перехватить запросы XHR/Ajax с помощью URL-адреса AngularJS