【问题标题】:How do I use transformRequest and transformResponse to modify data for a $resource?如何使用 transformRequest 和 transformResponse 修改 $resource 的数据?
【发布时间】:2015-06-13 18:24:51
【问题描述】:

我正在使用符合JSONAPI 的API,格式要求之一是所有数据(传入和传出)必须包装在data 对象中。所以我的请求看起来像:

{
  "data": {
    "email": "email@example.com",
    "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 是一个看起来像这样的工厂:

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 也会显示为未定义。

如何修改我的transformResponse 来解决这个问题?

【问题讨论】:

  • 嗯? data: JSON.parse JSON.stringify data你为什么要这么做?
  • 您需要了解session.$save() 是异步的,因此console.log session.token 将立即被调用并且在session.$save() 请求得到解决之前始终未定义。
  • 我也尝试使用.then 承诺,结果也一样
  • .then 不会帮助您,除非您返回承诺。资源自动行为不同于承诺。
  • 您的响应将作为资源记录,直到承诺得到解决。与session.token 相同,因为javascript 不会自动等待异步请求解决。请添加其余的资源定义。我意识到,我从未见过你从资源中返回什么。

标签: angularjs coffeescript


【解决方案1】:

我认为您想要的是通过承诺捕获您的资源响应:

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

【讨论】:

  • 也可以改成session.$save(function(result){//successCallback})
【解决方案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 in an AngularJS web app

Intercept XHR/Ajax requests with AngularJS http

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-31
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    • 1970-01-01
    • 2013-06-24
    • 2016-01-20
    • 2017-10-05
    相关资源
    最近更新 更多