【问题标题】:Is it possible to have an Angular js $http request inside another request?是否可以在另一个请求中包含 Angular js $http 请求?
【发布时间】:2015-12-14 00:37:53
【问题描述】:

我正在尝试在AngularJS 中发送请求以获取用于用户注册的令牌。获得令牌后,我将使用令牌发送另一个请求来注册用户。

但是第一个请求有效并且我获得了令牌,但第二个无效。

代码

facebookExample.controller('registerController', function($scope, $http, $localStorage, $location) {
  $scope.data = {};
  $scope.getToken = function() {
      $http.post('http://you-serve.org/api.php?action=createaccount&format=json&name=' + $scope.data.username + '&email=' + $scope.data.email + '&realname=' +
        $scope.data.firstname + ' ' + $scope.data.lastname +
        '&mailpassword=false&reason=Fun_and_profit&language=en&token').then(
        function(response) {
          return response.data.createaccount.token;
        }
        // End success
        ,
        function() {
          alert('error');
        } // End error 
      ); //End then
    } // End getToken

  $scope.register = function(myToken) {
      $http.post('http://you-serve.org/api.php?    action=createaccount&format=json&name=' +
        $scope.data.username + '&email=' +
        $scope.data.email + '&realname=' +
        $scope.data.firstname + ' ' +
        $scope.data.lastname +
        '&mailpassword=false&reason=Fun_and_profit&language=en&token=' + myToken).then(
        function(response) {
          alert("Registration successful !  You can log in now " + response.data.createaccount.username);
        },
        function(response) {
          alert(response.data.error.info);
        }); //End then
    } //End register


  $scope.signup = function() {
      register(getToken);
    } // End sign up
}); // End controller
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<ion-view ng-controller="registerController" title="Sign Up" view-title="Sign Up" name="login-view">

  <ion-content class="padding">
    <div class="list list-inset">
      <label class="item item-input">
        <input type="text" placeholder="Username" ng-model="data.username">
      </label>
      <label class="item item-input">
        <input type="password" placeholder="Password" ng-model="data.password">
      </label>


      <label class="item item-input">
        <input type="text" placeholder="Email" ng-model="data.email">
      </label>


      <label class="item item-input">
        <input type="text" placeholder="First Name" ng-model="data.firstname">
      </label>

      <label class="item item-input">
        <input type="text" placeholder="Last Name" ng-model="data.lastname">
      </label>



      <label class="item item-input">
        <input type="text" placeholder="City" ng-model="data.city">
      </label>




      <label class="item item-input">
        <input type="text" placeholder="Country" ng-model="data.country">
      </label>
    </div>
    <button class="button button-block button-calm" ng-click="register(getToken())">Sign Up</button>
  </ion-content>
</ion-view>

有人知道我该怎么做吗?

【问题讨论】:

  • 您可以创建一个局部变量,将令牌分配给局部变量。然后将其传递给第二个 http 请求。
  • 由于$http调用是异步的,你必须在第一个成功中调用第二个请求。

标签: javascript html angularjs http angularjs-http


【解决方案1】:

您可以使用 promise1.then(promise2) 链接承诺(这是 $http 返回的内容)。

因此,在您的情况下,链接 getToken 和注册的正确方法是:

$scope.getToken().then($scope.register)

(修改这两个函数后返回 $http 调用)

编辑:(进一步解释)

您正在尝试做的事情称为承诺链。本质上,按顺序执行两个或多个异步操作。来自html5rocks promise tutorial

排队异步操作

您还可以链接“then”以按顺序运行异步操作。

当您从“then”回调中返回某些内容时,这有点神奇。如果您返回一个值,则使用该值调用下一个“then”。但是,如果您返回类似 Promise 的内容,则下一个“then”会等待它,并且仅在该 Promise 解决(成功/失败)时调用。

其工作方式是,当您从 Promise.then() 函数返回一个值时,链中的下一个 then 函数将使用 .then() 函数的返回值或分辨率调用Promise,如果返回值为 Promise,则链会在继续之前等待此 Promise 解析。

因此(记住 $http 返回一个Promise 对象):

function a() {
    return $http.get('...').then(function (response) { return response.data; });
}

function b(data) {
    return $http.get('...'+data).then(function (response) { return response.data; });
}

要将两个函数链接在一起,以便使用a() 的结果调用b(),只需这样做:

a().then(b)

请阅读the tutorial on Promises 以更好地了解它们的工作原理。它们是 JavaScript 使异步操作更容易处理的最佳工具之一。

PS:在您的具体情况下,代码将是:

facebookExample.controller('registerController', function($scope, $http, $localStorage, $location) {
  $scope.data = {};

  function getToken() {
    return $http.post('http://you-serve.org/api.php?action=createaccount&format=json&name=' + $scope.data.username + '&email=' + $scope.data.email + '&realname=' + $scope.data.firstname + ' ' + $scope.data.lastname + '&mailpassword=false&reason=Fun_and_profit&language=en&token')
      .then(
        function(response) {
          return response.data.createaccount.token;
        },
        // End success
        function() {
          alert('error');
        } // End error 
      ); //End then
  } // End getToken

  function register(myToken) {
    return $http.post('http://you-serve.org/api.php?action=createaccount&format=json&name=' +
        $scope.data.username + '&email=' +
        $scope.data.email + '&realname=' +
        $scope.data.firstname + ' ' +
        $scope.data.lastname +
        '&mailpassword=false&reason=Fun_and_profit&language=en&token=' + myToken)
      .then(
        function(response) {
          alert("Registration successful !  You can log in now " + response.data.createaccount.username);
        },
        function(response) {
          alert(response.data.error.info);
        }
      ); //End then
  } //End register


  $scope.signup = function() {
    getToken().then(register);
  } // End sign up
}); // End controller

【讨论】:

  • 返回 $http 调用?例子?
  • 我认为@souldreamer 意味着 getToken() 应该返回一个可以被 register() 使用的对象(或其他值)
  • 感谢@souldreamer!
【解决方案2】:

你可以通过两种方式做到这一点:

方法 1 - 正常方式:

$scope.getToken = function() { 
    $http.post().then(function success(response) {
         // call register method here
         $scope.register(response.data.createaccount.token);
    }, function error(reason) {
      // do something
    });
};

方法 2 - 使用 $watch:

$scope.token = null;

 $scope.getToken = function() { 
        $http.post().then(function success(response) {
             // set the token value here
             $scope.token = response.data.createaccount.token;
        }, function error(reason) {
          // do something
        });
    };

$scope.$watch(function () { return $scope.token;}, 
function (newVal, oldVal) { 

if (newVal !== oldVal) {
   $scope.register(newVal);
}

});

【讨论】:

  • 拉比,感谢您的回复。我以前做过方法1。这是我得到的最接近工作的地方。然而,用户仍然没有在数据库中注册。我开始认为我的错误与请求以外的其他事情有关。
猜你喜欢
  • 1970-01-01
  • 2011-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-06
  • 1970-01-01
  • 2015-12-31
  • 1970-01-01
相关资源
最近更新 更多