How to call a function after completion of all requests - javascript

I have two AJAX requests one after another-
var firstResult;
var secondResult;
FirstAjaxrequest({
callback: function (options, success, response) {
if(success)
{
firstResult = true;
}
else
{
firstResult = false;
}
}
});
SecondAjaxrequest({
callback: function (options, success, response) {
if(success)
{
secondResult= true;
}
else
{
secondResult= false;
}
}
});
DisplayMessage(); // This function should display a message depending on
FirstResult and secondResult

You could create a variable for each request, signifying a successful request. Change this variable for each request respectively, when a successful request is made, then call your function.
Within your function simply check both variables, if they're both true, then both requests were successful, otherwise at least one was not and the if() condition will be false.
var firstResult = false,
secondResult = false;
FirstAjaxrequest({
callback: function (options, success, response) {
if(success) {
firstResult = true;
DisplayMessage();
}
}
});
SecondAjaxrequest({
callback: function (options, success, response) {
if(success) {
secondResult= true;
DisplayMessage();
}
}
});
function DisplayMessage(){
if(firstResult && secondResult){
//Both requests successful
} else {
//Either still waiting for a request to complete
// or a request was not successful.
}
}

There might be a better way to do it in EXTJS, but a plain JS solution is
var firstResult;
var secondResult;
var reqCount = 2;
var returnedCount = 0;
function isDone () {
returnedCount++
if ( returnedCount === reqCount ) {
console.log(firstResult, secondResult);
}
}
FirstAjaxrequest({
callback: function (options, success, response) {
if(success)
{
firstResult = true;
}
else
{
firstResult = false;
}
isDone();
}
});
SecondAjaxrequest({
callback: function (options, success, response) {
if(success)
{
secondResult= true;
}
else
{
secondResult= false;
}
isDone();
}
});

Give this a try
FirstAjaxrequest({
callback: function (options, success, response) {
if(success)
{
firstResult = true;
}
else
{
firstResult = false;
}
SecondAjaxrequest({
callback: function (options, success, response) {
if(success)
{
secondResult= true;
}
else
{
secondResult= false;
}
DisplayMessage(); // Now we have access to first and second result as the
//as the second request is within the scope of the first request
},
scope: this // We can pass the first request to the second request as the context
});
}
});

After the completion of each request, you should check if the result of the other one is received or not.
Some thing like this:
var result1 = null;
var result2 = null;
function DoAjax() {
$.get(url1, {}, function (data) {
result1 = data;
DoSth();
});
$.get(url2, {}, function (data) {
result2 = data;
DoSth();
});
}
function DoSth() {
if(result1 != null && result2 != null) {
//...
}
}

Warning: jQuery answer. I'm not sure if extjs has similar support for Deferreds and Promises.
This is a perfect opportunity to learn about jQuery Deferred:
$.when(firstAjaxrequest(...), secondAjaxrequest(...))
.then(function (firstResult, secondResult) {
...
});
This assumes your firstAjaxrequest and secondAjaxrequest functions both return Deferred or Promise objects, such as those returned by $.ajax.

Related

How to check xmlhttpRequest in AngularJS

How to check XMLHttpRequest While I'm getting status as 200 why it's not checking my xhr
angular.module("productManagement").controller('Employee', function ($scope, EmployeeService) {
var xhr = new XMLHttpRequest();
$scope.GetdataBySubmit = function () {
var GetData = EmployeeService.GetEmployeeData();
debugger;
GetData.then(function(d) {
if (xhr.status == "200") {
$scope.Employee = d.data;
$('#TadleData').show();
} else {
console.log("")
}
})
}
})
Here I'm Updating My GetEmployeeData Code
angular.module("productManagement").service("EmployeeService", function
($http) {
this.GetEmployeeData = function () {
var x=$http({
url: "http://localhost:9632/Api/Employee",
method:"Get",
data:JSON.stringify()
})
return x;
}
})
No need to define and use xhr variable
As you are using $http and returning Promise, Use the success callback handler response object.
GetData.then(function (response) {
if (response.status == 200) {
$scope.Employee = response.data;
$('#TadleData').show();
}
}, function (response) {
console.log("Do something on error")
})

One time call http request using angularjs

function get (id, ignore) {
var deferred = $q.defer();
$http.get('v1/info/' + id, {
ignoreAuthModule: ignore
})
.success(function (data) {
deferred.resolve(data.data);
})
.error(function (reason) {
deferred.reject(reason.message););
});
return deferred.promise;
}
init();
function init(){
users.get($routeParams.id)
.then(function (data) {
if(data.has_something === 1){
$scope.hasSomething = true;
}else{
$scope.hasSomething = false;
}
});
}
I have a Service that get the information about user using promise and Fetching information from the service with init function
//if i call init function this should call two times one from function initialization and other i'm calling it from service
how can i stop two times calling api I mean it should call one time if already called
You're using the explicit promise creation antipattern here, and your code could be much simpler. Here is how you can use memoization to avoid requesting the same user twice:
.factory('users', ['$http', function ($http) {
var userPromises = {};
function get (id, ignore) {
if (!userPromises[id]) {
userPromises[id] = $http.get('v1/info/' + id, {
ignoreAuthModule: ignore
})
.then(function (data) {
return data.data;
})
.catch(function (reason) {
throw new Error(reason.message);
});
}
return userPromises[id];
}
return {
get: get
};
});
You can assign your deferred.promise to some variable and then return that variable, and before your http call just check whether that variable is already defined or not
function get (id, ignore) {
if (angular.isUndefined(user)) {
var deferred = $q.defer();
$http.get('v1/info/' + id, {
ignoreAuthModule: ignore
}).then(function(response) {
if (response.status == 200) {
deferred.resolve(response.data);
} else {
deferred.reject(response.data);
};
user = deferred.promise;
return user;
} else {
return user;
}
}
This way your api will get called only once.

Call a function in another javascript function synchronously

I am trying to call checkLoginStatus function in getUserAlbum function, in the getUserAlbum I am catching the response return by checkLoginStatus and on behalf of that response I need to work under the getUserAlbum function.
But the problem is this getUserAlbum function does not wait for the response and execute the next line that I do not want.
Here is my functions:
var accessToken = '';
checkLoginStatus = function () {
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
accessToken = response.authResponse.accessToken;
console.log(accessToken + ' => in check login status');
return accessToken;
} else {
return false;
}
});
}
getUserAlbum = function () {
var token = checkLoginStatus();
console.log(token + ' => in get album function'); // it log undefined here that is why else part executes.
if(token) {
FB.api(
"/me/albums/", {'accessToken': token},
function (response) {
if (response && !response.error) {
console.log(response);
}
}
);
} else {
alert("You are not logged in");
}
}
Someone can please help me to solve this issue.
FB.getLoginStatus is asynchronous...Use callbacks as response from FB api will be asynchronous. You can not be certain when will it be received.
Your function is executed and control is returned before the response is received hence it will be undefined.
In callbacks, you pass function as argument will will be executed later in the program when needed.
var accessToken = '';
var checkLoginStatus = function(callback) {
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
accessToken = response.authResponse.accessToken;
callback(accessToken);
} else {
callback(false);
}
});
}
var getUserAlbum = function() {
checkLoginStatus(function(token) {
console.log(token + ' => in get album function'); // it log undefined here that is why else part executes.
if (token) {
FB.api(
"/me/albums/", {
'accessToken': token
},
function(response) {
if (response && !response.error) {
console.log(response);
}
}
);
} else {
alert("You are not logged in");
}
});
}

Angularjs FB login using factory

I am new to angularjs.I am using factories where i have written the fb login code.
And during the last step i am sending all the data to my server where the user is registered in my database and the token is sent.
Here is the code.
'use strict'
APP.factory('authenticationFactory',['ENV','$http','$rootScope', function (ENV,$http,$rootScope) {
return {
socialLogin:function(data){
return $http.post($rootScope.apiURL+'sociallogin',data).then(function (resp) {
if(resp.status == 200) {
return resp.data;
}
})
},
fbLogin: function () {
var FB = window.FB;
var scopes = 'public_profile,email';
var that = this;
FB.login(function (response) {
return that.facebookStatusChangeCallback(response);
}, {scope: scopes});
},
facebookStatusChangeCallback: function(response){
if (response.status === 'connected') {
// Logged into your app and Facebook.
var r = this.facebookApiRequest(response);
console.log(r);
} else if (response.status === 'not_authorized') {
// The person is logged into Facebook, but not your app.
console.log('Please log into this app.');
} else {
// The person is not logged into Facebook, so we're not sure if
// they are logged into this app or not.
console.log('Please log into Facebook.');
}
},
facebookApiRequest: function (authResponse) {
var that = this;
var r = FB.api('/me?fields=id,name,email,gender,first_name,last_name,age_range,link,birthday', function (response) {
var r = FB.api("/" + response.id + "/picture?height=720", function (pictureResponse) {
if (pictureResponse && !pictureResponse.error) {
/* handle the result */
response.profile_pic = pictureResponse.data.url;
response.access_token = authResponse.authResponse.accessToken;
response.provider = 'facebook';
response.devicetoken = '';
response.full_name = response.first_name+' '+response.last_name;
var r = that.socialPluginLogin(response).then(function (resp) {
return that.resp;
});
return r;
} else {
console.log('error while fatching fb pic');
}
});
console.log(r);
});
console.log(that);
},
socialPluginLogin : function (data) {
var resp = this.socialLogin(data).then(function (resp) {
return resp;
});
return resp;
}
};
}]);
I am calling the fbLogin() function from my controller. i need the response from the function socialLogin() so that i can change the state.
Where am i going wrong.??
The answer was pointing in the wrong direction, another try:
Your function fbLogin should return a promise, which can be resolved by socialLogin later. Since fbLogin doesn't return a thing, you don't receive any signal from the completed login.
See this:
// We add $q here
APP.factory('authenticationFactory',['ENV','$http','$rootScope','$q', function (ENV,$http,$rootScope,$q) {
var loginPromise;
return {
socialLogin:function(data){
return $http.post($rootScope.apiURL+'sociallogin',data).then(function (resp) {
if(resp.status == 200) {
// This is your connection to the controller
loginPromise.resolve(resp.data);
return resp.data;
}
})
},
fbLogin: function () {
var FB = window.FB;
var scopes = 'public_profile,email';
var that = this;
FB.login(function (response) {
return that.facebookStatusChangeCallback(response);
}, {scope: scopes});
// Create and return a promise
loginPromise = $q.defer();
// EDIT: My fault, return the promise:
return loginPromise.promise;
},
//...
And add this to the controller:
authenticationFactory.fbLogin().then(function(data){
// Check it out:
console.dir(data);
})
Additional things you should consider:
Define your functions in the function body, not in the return statement. You can eliminate that=this this way
Only return the API, not all the functions
Read up on promises, they are the way to go in the angular world. You might as well use callbacks, but those are tedious to handle.
Change your socialLogin function to below, your function would return a promise object which you can consume in socialPluginLogin via then which you are already doing.
socialLogin:function(data){
return $http.post($rootScope.apiURL+'sociallogin',data)
},

Backbone router using jQuery $.get() promise to determine logged in state of user not working as expected

I'm trying to use a jQuery promise to make authenticated.done wait until the $.get() in .isAuthenticated returns, but I'm not getting the result I was expecting... the function inside authenticated.done runs before the preceding $.get() returns and thus does not work. Am I doing something wrong or am I going about this in entirely the wrong way?
isAuthenticated : function() {
// make a request to the server and see if the response is a login form or not
// this should just return true or false, not actually handle login etc
var authenticated = false;
console.log("authenticating...");
var ready = Promise.from(null);
$.get("/loggedin")
.then(function(data, textStatus) {
var rtnVal = false;
if (textStatus == "success" && !(data instanceof Object)) {
console.log("failure returned");
} else {
console.log("success returned");
rtnVal = true;
}
return rtnVal;
})
.done(function(result) {
authenticated = result;
});
return ready.then(function () {
return authenticated;
})
},
render: function (view) {
if(this.currentView) this.currentView.destroy();
var authenticated = this.isAuthenticated();
authenticated.done(function (response) {
if (response == true) {
console.log("Authentication success!");
// set the currentView
this.currentView = view;
// render the new view
this.currentView.render();
// set the view's menu items
if (this.currentView.navLink !== undefined) {
$(this.currentView.navLink).addClass("active");
}
} else {
console.log("Authentication failed...");
view = new app.LoginView();
view.render();
this.currentView = view;
}
});
return this;
}
And the console output:
authenticating... router.js:45
Authentication failed... router.js:89
success returned router.js:55
Here's what your code should look like using jQuery's Deferred/Promise objects:
{
authenticate: function () {
var authentication = $.Deferred();
$.get("/loggedin")
.then(function (data, textStatus) {
if (textStatus === "success" && !(data instanceof Object)) {
authentication.resolve(data, textStatus);
} else {
authentication.reject(data, textStatus);
}
});
return authentication.promise();
},
render: function (view) {
if (this.currentView) this.currentView.destroy();
this.authenticate()
.done(function (data, textStatus) {
this.currentView = view;
this.currentView.render();
$(this.currentView.navLink).addClass("active");
})
.fail(function (data, textStatus) {
view = new app.LoginView();
view.render();
this.currentView = view;
});
return this;
}
};
Notes:
since then is called regardless of success or failure of the GET request you don't need a fail callback.
I've renamed the function to the more appropriate authenticate, because it is an action, not a state
jQuery does not care if you pass undefined to it, so your if (this.currentView.navLink !== undefined) check is superfluous
You might want to use data and textStatus in the authentication callbacks somehow. If you don't need them, call resolve() or reject() without arguments.
I do not know what is Promise object that you are using, but using standard jquery deferred object the code will look:
isAuthenticated : function() {
// make a request to the server and see if the response is a login form or not
// this should just return true or false, not actually handle login etc
var authenticated = $.Deferred();
console.log("authenticating...");
$.get("/loggedin")
.then(function(data, textStatus) {
if (textStatus == "success" && !(data instanceof Object)) {
console.log("failure returned");
authenticated.reject();
} else {
console.log("success returned");
authenticated.resolve();
}
}, function () {
authenticated.reject();
});
return authenticated;
},
render: function (view) {
if(this.currentView) this.currentView.destroy();
var authenticated = this.isAuthenticated();
authenticated.done(function (response) {
if (response == true) {
console.log("Authentication success!");
// set the currentView
this.currentView = view;
// render the new view
this.currentView.render();
// set the view's menu items
if (this.currentView.navLink !== undefined) {
$(this.currentView.navLink).addClass("active");
}
} else {
console.log("Authentication failed...");
view = new app.LoginView();
view.render();
this.currentView = view;
}
});
authenticated.fail(function () {console.log('failed')});
return this;
}

Categories

Resources