如何通过后续服务调用 return HTTP 响应

How to return HTTP response through subsequent service call

我在通过一系列通用函数 return 将数据从 Web API 发送到 Angular 表单时遇到问题。我以最简单的形式给出代码以理解问题:-

HTML 形式:-

<label>Request Number</label>
<input type="text" id="txtRequestNum" ng-model="md_reqnumber" />
<label>Employee Number</label>
<input type="text" id="txtEmployeeId" ng-model="md_number" ng-disabled="true" />

Controller.js

var myApp = angular.module('appHome');
myApp.controller("ctrlEmployeeAdd", ['$scope', 'CommonFunctionFactory', function ($scope,  CommonFunctionFactory) {
    CommonFunctionFactory.AddMasterData($scope.md_reqnumber)
        .then(function (dataSuccess) {
            $scope.number = dataSuccess;
        }, function (dataError) {
        });
}]);

CommonFunctionFactory.js

var appService = angular.module('appHome');
appService.factory('CommonFunctionFactory', ['MetadataOrgFactory', function (MetadataOrgFactory) {
    var dataFactory = {};

    dataFactory.AddMasterData = function (objData) {
        MetadataOrgFactory.postApiCall('addemployee', objData, function (dataSuccess) {
            alert("The request has been completed succesfully");
            return dataSuccess; 
        }, function (dataError) {
        });
    }
    return dataFactory;
}])

ApiCallService.js

var appService = angular.module('appHome');
appService.factory('MetadataOrgFactory', ['$http', '$q', function ($http, $q) {
    var dataFactory = {};
    var url = 'http://localhost:XXXXX';

    dataFactory.postApiCall = function (controllerName, objData, callbackSuccess, callbackError) {

        $http.post(url + '/api/' + controllerName, objData).then
            (function success(response) {
                alert("Success");
                callbackSuccess(response.data);
            }, function error(response) {
                callbackError(response.status);
            });
    };

    return dataFactory;
}])

WebApi.cs

[Authorize]
[Route("api/addemployee")]
[HttpPost]
public int AddEmployee(EmployeeViewModel vmEmployee)
{
    return 54302 //Just for simplicity here, returning hard coded value
}

我能够在 ApiCallService.js 中获得上述硬编码值,也能够在 datasuccess 变量中获得CommonFunctionFactory.js 但无法将值 return 返回到 Controller.js。这是我的实际问题。

此外 angular 在 Controller.js 中定义的承诺在从 Web API 获得响应后给出以下错误:-

Cannot read property 'then' of undefined

请帮我解决问题。

postApiCall 函数没有 returning 任何东西。你需要 return $http:

dataFactory.postApiCall = function (controllerName, objData, callbackSuccess, callbackError) {
  return $http.post(url + '/api/' + controllerName, objData)
    .then(function success(response) {
      alert("Success");
      callbackSuccess(response.data);
    },
    function error(response) {
      callbackError(response.status);
    });
};

然后您需要对 MetadataOrgFactory.postApiCall 执行相同的操作,方法是在其前面添加一个 return:

return MetadataOrgFactory.postApiCall('addemployee', objData, function (dataSuccess) {
  alert("The request has been completed succesfully");
  return dataSuccess; 
  },
  function (dataError) {}
);

现在,您已经 return 编辑了请求,以便调用 CommonFunctionFactory.AddMasterData($scope.md_reqnumber) 将有一个可用的 then 方法。

我想它只是 return 之前未定义。您可以通过注销 CommonFunctionFactory.AddMasterData($scope.md_reqnumber)

的值来查看

正如 AnthW 指出的那样,您非常接近,但我认为您的问题围绕着您是什么和不是什么 returning。我的更改如下,它不需要更改您的 controller.js 或服务器文件,只需要更改两个工厂。

CommonFunctionFactory.js

为此,我会亲自删除这个工厂,但如果你想保留它,我会 return $http 调用,这样在你的控制器中你可以使用 then 和访问 returned 变量。

var appService = angular.module('appHome');
appService.factory('CommonFunctionFactory', ['MetadataOrgFactory', function (MetadataOrgFactory) {
    var dataFactory = {};

    dataFactory.AddMasterData = function (objData) {
        return MetadataOrgFactory.postApiCall('addemployee', objData);
    }
    return dataFactory;
}])

ApiCallService.js

正如 AnthW 在他的回答中指出的那样,您没有 returning $http 调用,这就是您看到未定义的原因。此外,在使用 promises 时没有理由使用回调函数,promises 只是处理相同用例的不同方式。在此代码中,我将删除您的回调,我们正在 return 承诺,而承诺是 return 成功对象或错误对象。

var appService = angular.module('appHome');
appService.factory('MetadataOrgFactory', ['$http', '$q', function ($http, $q) {
    var dataFactory = {};
    var url = 'http://localhost:XXXXX';

    dataFactory.postApiCall = function (controllerName, objData) {

        var promise = $http.post(url + '/api/' + controllerName, objData)
            .then(function(response) {
                alert("Success");
                return response.data;
            }, function(response) {
                return response.status;
            });

        return promise;
    };

    return dataFactory;
}])

因此,总而言之,我的更改是让您的 ApiCallService.js return 由 $http 创建的承诺。 CommonFunctionFactory.js 将只处理 return 这个对控制器的承诺。在你的控制器中,你已经在期待一个承诺,所以这个 returned 承诺将在你的控制器中被正确访问,你将能够检索 returned 值。