I am trying to send a request in AngularJS
to get a token for user registration. Once I get the token, I am sending another request using the token to register the user.
However the first request works and I get the token, but the second one does not work.
Code
facebookExample.controller('registerController', function($scope, $http, $localStorage, $location) {
$scope.data = {};
$scope.getToken = function() {
$http.post('.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('.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=".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>
I am trying to send a request in AngularJS
to get a token for user registration. Once I get the token, I am sending another request using the token to register the user.
However the first request works and I get the token, but the second one does not work.
Code
facebookExample.controller('registerController', function($scope, $http, $localStorage, $location) {
$scope.data = {};
$scope.getToken = function() {
$http.post('http://you-serve/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/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./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>
Anyone know how I can I do this ?
Share Improve this question edited Dec 13, 2015 at 16:05 Raz0rwire 6979 silver badges18 bronze badges asked Dec 13, 2015 at 15:04 codigomonstruocodigomonstruo 1,0911 gold badge14 silver badges48 bronze badges 2- You can create a local variable, assign the token to the local variable. And then pass it to second http request. – Shaohao Commented Dec 13, 2015 at 15:08
-
Since
$http
call is async, you will have to call second request inside success of first. – Rajesh Commented Dec 13, 2015 at 15:11
2 Answers
Reset to default 7You can chain promises (which is what $http returns) by using promise1.then(promise2).
So in your case the correct way to chain getToken and register is:
$scope.getToken().then($scope.register)
(after you modify the two functions to return the $http calls)
Edit: (further explanation)
What you are trying to do is called promise chaining. Esentially, executing two or more asynchronous operations in sequential order. From the html5rocks promise tutorial:
Queuing asynchronous actions
You can also chain "then"s to run async actions in sequence.
When you return something from a "then" callback, it's a bit magic. If you return a value, the next "then" is called with that value. However, if you return something promise-like, the next "then" waits on it, and is only called when that promise settles (succeeds/fails).
The way this works is that when you return a value from the Promise
or the .then()
function, then the next then function in the chain is called with the return value of the .then()
function or the resolution of the Promise
, and if the return value is a Promise
, the chain then waits on this Promise
to resolve before it continues.
Thus (and remember than $http returns a Promise
object):
function a() {
return $http.get('...').then(function (response) { return response.data; });
}
function b(data) {
return $http.get('...'+data).then(function (response) { return response.data; });
}
To chain the two functions together, so that b()
gets called with the result of a()
, just do this:
a().then(b)
Do read the tutorial on Promise
s to get a better handle on how they work. They are one of the best tools JavaScript has to make asynchronous operations easier to handle.
PS: In your specific case, the code would be:
facebookExample.controller('registerController', function($scope, $http, $localStorage, $location) {
$scope.data = {};
function getToken() {
return $http.post('http://you-serve/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/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
you can do it in two ways :
Method 1 - Normal Way:
$scope.getToken = function() {
$http.post().then(function success(response) {
// call register method here
$scope.register(response.data.createaccount.token);
}, function error(reason) {
// do something
});
};
Method 2 - Use $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);
}
});