waiting for multiple asynchronous facebook requests - javascript

Need to wait for several requests to facebook to complete before taking a final action on the page (updating the count of how many requests returned info) but not sure how to approach it.
How do you check that each function is complete and update a counter before firing a function. window.load is too early unless the page is refreshed after login...?
window.fbAsyncInit = function () {
FB.init({
appId: 'id', // App ID
//channelUrl: '//facebookdev.smithbrosagency.com/LOL/xss_channel.htm', // Channel File
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: true // parse XFBML
});
getStatus();
//Subscribe to events
FB.Event.subscribe('auth.statusChange', function (response) { if (response.authResponse) { getStatus(); } });
FB.Event.subscribe('auth.login', function (response) { if (response.status === 'connected') { getStatus(); } });
};
function getStatus() {
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
setPanel('results'); // connected
var accessToken = response.authResponse.accessToken;
var obj = getPermissionsObject(function (permissions) {
getUserInfo(response);
getUserPhotos(response, accessToken);
getFriends(response, accessToken);
getUserLocations(response, accessToken);
getUserMusic(response, accessToken);
getUserMovies(response, accessToken);
});
} else {
setPanel('login'); // not logged in or unauthorized
}
});
}
function getUserPhotos(response, accessToken) {
FB.api('/me/photos?access_token=' + accessToken, function (response) {
var photoList = response.data;
var len = photoList.length;
if (len >= 3) {
var max = 3;
if (len > max) { len = max }; // cap it at 3
for (var i = 0; i < len; i++) {
(function () {
var j = i;
var idx = i + 1;
$('.result2 .option' + idx + ' input').val(photoList[i].picture);
$('.result2 .option' + idx + ' img').attr("src", photoList[i].picture);
})();
}
$('div.result2').addClass("active");
$('#q2 input').val(1); // add to hidden to count results
}
else {
// hide & subtract from total questions
$('div.result2').addClass("inactive");
$('#q2 input').val(0);
}
});
}
$(window).load(function () {
$.when($('#q2 input').val() != '' && $('#q4 input').val() != '' && $('#q5 input').val() != '').then(test());
function test() {
// calc total questions
var total = 0;
$("#Results div input[hidden]").each(function () {
total += $(this).val() * 1;
});
alert(total);
}
});

I'm not sure if I understand you correctly but it seems you need to implement an object like this:
<script type="text/javascript">
//Monitoring object
function RequestStatusMonitor()
{
this.resetRequests();
}
//IDs of the requests you need to monitor
RequestStatusMonitor.prototype.requests=["firstRequest","secondRequest","thirdRequest"];
//Status of the requests
RequestStatusMonitor.prototype.requestsCompleted=[];
//Set all requests to incomplete state
RequestStatusMonitor.prototype.resetRequests = function()
{
this.requestsCompleted = [];
for(var it in this.requests)
{
this.requestsCompleted[this.requests[it]] = false;
}
}
//Set status for a request determined by requestName
RequestStatusMonitor.prototype.setRequestStatus = function(requestName, status)
{
this.requestsCompleted[requestName] = status;
}
//Check if all requests are completed
RequestStatusMonitor.prototype.allRequestsAreCompleted = function()
{
for(var it in this.requestsCompleted)
{
if(!this.requestsCompleted[it])
{
return false;
}
}
return true;
}
//----------------------------------------------------------------------------------
//Usage Example
var monitor = new RequestStatusMonitor();
function onFirstRequestFinished(/*necessary parameters*/)
{
monitor.setRequestStatus("firstRequest", true);
checkCompleted();
}
function onSecondRequestFinished(/*necessary parameters*/)
{
monitor.setRequestStatus("secondRequest", true);
checkCompleted();
}
function onThirdRequestFinished(/*necessary parameters*/)
{
monitor.setRequestStatus("thirdRequest", true);
checkCompleted();
}
function checkCompleted()
{
if(monitor.allRequestsAreCompleted())
{
//Do what you need after all requests are completed
alert("All requests are completed");
}
}
onFirstRequestFinished();
onThirdRequestFinished();
onSecondRequestFinished();
</script>

Related

Looping array that generates ajax call, i need the first call to finish before next one starts

Simply i just loop an array, and submit data with get in the loops, but i runs so fast that the server stops running. I mini Ddos myself doing this. How i can i make the loop wait until the calls finish, perhaps adding a 1 sek break between loops
$( document ).on("submit", "#add_links", function() {
var error = 0;
var success = 0;
var total = 0;
//Gets data from input field
var new_urls = $("#new_urls").val();
var array_urls = new_urls.split("\n");
var promiss = [];
array_urls.forEach(function(entry) {
var request = $.get("action.php",
{
add_link: "1",
url: encodeURIComponent(entry.trim()),
},
function(data, status){
console.log("Data: " + data + "\nStatus: " + status);
if (data == 1)
{
success++;
total++;
//update fields removed in this post
$("#success_count").html((success));
$("#total_count").html((total));
}
if (data == 2) {
error++;
total++;
//update fields removed in this post
$("#error_count").html((error));
$("#total_count").html((total));
}
});
promiss.push(request);
});
$.when.apply(null, promiss).done(function(){
//do something when done;
});
return false;
});
You could use recursive function to achieve this.
Example
$(document).on("submit", "#add_links", function() {
var error = 0;
var success = 0;
var total = 0;
var new_urls = $("#new_urls").val();
var array_urls = new_urls.split("\n");
var promiss = [];
let index = 0;
function sendAjaxCall() {
if(count >= array_urls.length) return;
var request = $.get(
"action.php",
{
add_link: "1",
url: encodeURIComponent(array_urls[index].trim())
},
function(data, status) {
console.log("Data: " + data + "\nStatus: " + status);
if (data == 1) {
success++;
total++;
$("#success_count").html(success);
$("#total_count").html(total);
}
if (data == 2) {
error++;
total++;
$("#error_count").html(error);
$("#total_count").html(total);
}
count++;
promiss.push(request);
sendAjaxCall();
}
);
}
$.when.apply(null, promiss).done(function() {
$("#close_bug_reportwindow").html(
"Import done, close tab by clicking here"
);
$("#close_icon").html('(<i class="fas fa-times"></i>)');
$("#progress").remove();
});
return false;
});

Calling setInterval multiple times then Clearing interval , polling not stopped

As my loop is so fast, the intervals are overlapping and not able to stop one timerId. here is my code:
data = ['115536', '117202']; // BARCODES AVAILABLE ON A4 SHEET //
var scan_delay = 500; // USER AVG SCANNING SPEED PER BARCODE //
var timerId;
var scannedItemsList = []; // ITEMS WHICH ARE SCANNED BY SEEING A4 SHEET BY THE USER //
var tableDataList = []; // TO SHOW DATA WHICH WE GOT FROM API //
Jbin
try {
var data = ['115536', '117202']; // BARCODES AVAILABLE ON A4 SHEET //
var scan_delay = 500; // USER AVG SCANNING SPEED PER BARCODE //
var timerId;
var scannedItemsList = []; // ITEMS WHICH ARE SCANNED BY SEEING A4 SHEET BY THE USER //
var tableDataList = []; // TO SHOW DATA WHICH WE GOT FROM API //
execute(data);
function execute(data) {
var i = 0;
scanSimulatorWithADelay(data, i);
}
function scanSimulatorWithADelay(data, i) {
setTimeout(function () {
getJobDetailsByCallingAPI(data[i], i);
i++;
if (data.length > i) {
scanSimulatorWithADelay(data, i);
} else {
i = 0;
}
}, scan_delay);
}
function getJobDetailsByCallingAPI(jobNumber, index) {
scannedItemsList.push(jobNumber);
//poll_for_jobs_count_which_are_scanned_but_waiting_to_add_to_table
startPolling();
//Simulate API to get response after every 3 seconds//
var apiDelay = (index + 1) * 3000;
setTimeout(function () {
console.log('API CALLED AT ' + new Date().toLocaleTimeString());
CallTheAPI(jobNumber);
}, apiDelay);
}
function CallTheAPI(jobNumber) {
console.log("JOB NO " + jobNumber + " API response Recd");
tableDataList.push(jobNumber);
}
function startPolling() {
var pollStatus = '';
timerId = setInterval(() => {
debugger;
console.log('timerId when starting interval ' + timerId);
var jobsWhichAreScannedButNotLoaded = jobsWhichAreScannedButNotLoadedStill();
console.log("$$$$$$ jobsWhichAreScannedButNotLoaded = " + jobsWhichAreScannedButNotLoaded.length);
if (jobsWhichAreScannedButNotLoaded.length === 0) {
console.log("### Inteval Cleared ### " + timerId);
//CLEAR TIMER
clearInterval(timerId);
} else {
pollStatus = 'Polling inprogress and the pollID ' + timerId;
}
console.log('####' + pollStatus);
}, 2000);
}
function jobsWhichAreScannedButNotLoadedStill() {
let stillLoadingJobs = [];
scannedItemsList.forEach(scannedItemsListJobNumber => {
let foundJobInsideTable = false;
if (scannedItemsListJobNumber) {
foundJobInsideTable = tableDataList.indexOf(scannedItemsListJobNumber) > -1;
if (!foundJobInsideTable) {
stillLoadingJobs.push(scannedItemsListJobNumber);
}
}
}); // End of scannedItemsList forEach loop
if (stillLoadingJobs.length > 0) {
return stillLoadingJobs;
}
return [];
}
} catch (error) { throw error; }
Your timer_id variable is on the global scope and hence overwritten every time you call startPolling.
So when you'll call clearInterval(timer_id), timer_id will be the id of the last setInterval, and the first one will keep running endlessly.
Simply add a var in your startPolling function so that timer_id be scoped correctly, and that it doesn't get overwritten by next call.
try {var data = ['115536', '117202'];
var scan_delay = 500;
// remove this one
//var timerId;
var scannedItemsList = [];
var tableDataList = [];
execute(data);
function execute(data) {
var i = 0;
scanSimulatorWithADelay(data, i);
}
function scanSimulatorWithADelay(data, i) {
setTimeout(function () {
getJobDetailsByCallingAPI(data[i], i);
i++;
if (data.length > i) {
scanSimulatorWithADelay(data, i);
} else {
i = 0;
}
}, scan_delay);
}
function getJobDetailsByCallingAPI(jobNumber, index) {
scannedItemsList.push(jobNumber);
//poll_for_jobs_count_which_are_scanned_but_waiting_to_add_to_table
startPolling();
//Simulate API to get response after every 3 seconds//
var apiDelay = (index + 1) * 3000;
setTimeout(function () {
console.log('API CALLED AT ' + new Date().toLocaleTimeString());
CallTheAPI(jobNumber);
}, apiDelay) ;
}
function CallTheAPI(jobNumber) {
$.ajax({
url: "https://jsonplaceholder.typicode.com/todos/1",
type: "GET",
async: true,
success: function (response) {
console.log("JOB NO " + jobNumber + " API response Recd");
tableDataList.push(jobNumber);
}
});
}
function startPolling() {
var pollStatus = '';
/////////
///HERE
/////////
// Declare timerId in startPolling scope
/////////
var timerId = setInterval(() => {
debugger;
console.log('timerId when starting interval '+ timerId);
var jobsWhichAreScannedButNotLoaded = jobsWhichAreScannedButNotLoadedStill();
console.log("$$$$$$ jobsWhichAreScannedButNotLoaded = "+ jobsWhichAreScannedButNotLoaded.length);
if (jobsWhichAreScannedButNotLoaded.length === 0) {
console.log("### Inteval Cleared ### "+ timerId);
//CLEAR TIMER
clearInterval(timerId);
} else {
pollStatus = 'Polling inprogress and the pollID ' + timerId;
}
console.log('####' + pollStatus);
}, 2000);
}
function jobsWhichAreScannedButNotLoadedStill() {
let stillLoadingJobs = [];
scannedItemsList.forEach(scannedItemsListJobNumber => {
let foundJobInsideTable = false;
if (scannedItemsListJobNumber) {
foundJobInsideTable = tableDataList.indexOf(scannedItemsListJobNumber) > -1;
if (!foundJobInsideTable) {
stillLoadingJobs.push(scannedItemsListJobNumber);
}
}
}); // End of scannedItemsList forEach loop
if (stillLoadingJobs.length > 0) {
return stillLoadingJobs;
}
return [];
}
} catch (error) { throw error; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Return text when checkbox selected

In my site, I have a form that users can click on a checkbox to select "available". I want to have "Yes" or "No" returned in the displayArticle function based on whether the box is checked or not. Right now it returns True or False, which is not optimal. How can I code this?
Here is my entire JS code:
App = {
web3Provider: null,
contracts: {},
account: 0x0,
loading: false,
init: function() {
return App.initWeb3();
},
initWeb3: function() {
// initialize web3
if(typeof web3 !== 'undefined') {
//reuse the provider of the Web3 object injected by Metamask
App.web3Provider = web3.currentProvider;
} else {
//create a new provider and plug it directly into our local node
App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
}
web3 = new Web3(App.web3Provider);
App.displayAccountInfo();
return App.initContract();
},
displayAccountInfo: function() {
web3.eth.getCoinbase(function(err, account) {
if(err === null) {
App.account = account;
$('#account').text(account);
web3.eth.getBalance(account, function(err, balance) {
if(err === null) {
$('#accountBalance').text(web3.fromWei(balance, "ether") + " ETH");
}
})
}
});
},
initContract: function() {
$.getJSON('RentalContract.json', function(chainListArtifact) {
//added May24 to json file name
// get the contract artifact file and use it to instantiate a truffle contract abstraction
App.contracts.RentalContract = TruffleContract(chainListArtifact);
// set the provider for our contracts
App.contracts.RentalContract.setProvider(App.web3Provider);
// listen to events
App.listenToEvents();
// retrieve the article from the contract
return App.reloadArticles();
});
},
reloadArticles: function() {
//avoid reentry bugs
if(App.loading){
return;
}
App.loading = true;
// refresh account information because the balance might have changed
App.displayAccountInfo();
var chainListInstance;
App.contracts.RentalContract.deployed().then(function(instance) {
chainListInstance = instance;
return chainListInstance.getArticlesForSale();
}).then(function(articlesIds) {
// retrieve the article placeholder and clear it
$('#articlesRow').empty();
for(var i = 0; i < articlesIds.length; i++){
var articleId = articlesIds[i];
chainListInstance.articles(articleId.toNumber()).then(function(article){
App.displayArticle(article[0], article[1], article[3], article[4], article[5], article[6], article[7]);
});
}
App.loading = false;
}).catch(function(err) {
console.error(err.message);
App.loading = false;
});
},
//displayArticle: function(id, seller, beds, baths, propaddress, rental_price, property_type, description, available, contact_email) {
displayArticle: function(id, seller, propaddress, rental_price, description, available, contact) {
var articlesRow = $('#articlesRow');
//var etherPrice = web3.fromWei(price, "ether");
var articleTemplate = $("#articleTemplate");
//articleTemplate.find('.panel-title').text(propaddress);
//articleTemplate.find('.beds').text(beds);
//articleTemplate.find('.baths').text(baths);
articleTemplate.find('.propaddress').text(propaddress);
articleTemplate.find('.rental_price').text('$' + rental_price);
//articleTemplate.find('.property_type').text(property_type);
articleTemplate.find('.description').text(description);
articleTemplate.find('.available').text(available);
articleTemplate.find('.contact').text(contact);
// articleTemplate.find('.article_price').text(etherPrice + " ETH");
articleTemplate.find('.btn-buy').attr('data-id', id);
// articleTemplate.find('.btn-buy').attr('data-value', etherPrice);
//seller
if(seller == App.account){
articleTemplate.find('.article-seller').text("You");
articleTemplate.find('.btn-buy').hide();
}else{
articleTemplate.find('.article-seller').text(seller);
articleTemplate.find('.btn-buy').show();
}
//add this new article
articlesRow.append(articleTemplate.html());
},
sellArticle: function() {
// retrieve the detail of the article
// var _article_name = $('#article_name').val();
var _description = $('#description').val();
//var _beds = $('#beds').val();
//var _baths = $('#baths').val();
var _propaddress = $('#propaddress').val();
var _rental_price = $('#rental_price').val();
//var _property_type = $('#property_type').val();
var _available = $('#available').val();
var _contact = $('#contact').val();
// var _article_price = $('#article_price').val();
// var _price = web3.toWei(parseFloat($('#article_price').val() || 0), "ether");
// if((_description.trim() == '') || (rental_price == 0)) {
// nothing to sell
// return false;
// }
App.contracts.RentalContract.deployed().then(function(instance) {
//return instance.sellArticle(_description, _beds, _baths, _propaddress, _rental_price, _property_type, _available, _contact_email, {
return instance.sellArticle(_propaddress, _rental_price, _description, _available, _contact,{
from: App.account,
gas: 500000
});
}).then(function(result) {
}).catch(function(err) {
console.error(err);
});
},
// listen to events triggered by the contract
listenToEvents: function() {
App.contracts.RentalContract.deployed().then(function(instance) {
instance.LogSellArticle({}, {}).watch(function(error, event) {
if (!error) {
$("#events").append('<li class="list-group-item">' + event.args._propaddress + ' is now for sale</li>');
} else {
console.error(error);
}
App.reloadArticles();
});
instance.LogBuyArticle({}, {}).watch(function(error, event) {
if (!error) {
$("#events").append('<li class="list-group-item">' + event.args._buyer + ' bought ' + event.args._propaddress + '</li>');
} else {
console.error(error);
}
App.reloadArticles();
});
});
},
buyArticle: function() {
event.preventDefault();
// retrieve the article price and data
var _articleId = $(event.target).data('id');
var _price = parseFloat($(event.target).data('value'));
App.contracts.RentalContract.deployed().then(function(instance){
return instance.buyArticle(_articleId, {
from: App.account,
value: web3.toWei(_price, "ether"),
gas: 500000
});
}).catch(function(error) {
console.error(error);
});
}
};
$(function() {
$(window).load(function() {
App.init();
});
});
If I understand what you're trying to do, perhaps this will work for you.
var isChecked = '';
if (articleTemplate.find('.available').checked === true)
{ isChecked = 'yes'} else
{ isChecked = 'no'}
.
.
.
return isChecked;
Do this:
articleTemplate.find( '.available' ).text( available ? 'Yes' : 'No' );
Example:
function returnValue() {
$( '#val' ).text( $( '#chk' ).is( ':checked' ) ? 'Yes' : 'No' )
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" id="chk" onclick="returnValue()" />
<label for="chk">Available</label>
<h2 id="val"></h2>

Http Request base on priority using AngularJs?

I am sending multiple http request using Angularjs.
Can we set priority for some requests.
I am keep sending http request according to my need. I can't send request http request on sequence basis
Can somehow we can set priority
Any Idea?
Thanks
Hey id suggest you use a http Intercepter Service there you can monitor every request and response smth like this this is just an idea
.factory('httpInterceptor', function ($q, $rootScope, $filter) {
var canceller = $q.defer();
var numLoadings = 0;
var serialRequests = false;
var timeO;
var time1;
var loadingbar = { loading: "<progress value='?' max='10'></progress>" };
var loadingspinner = { loading: '<ion-spinner icon="crescent"></ion-spinner>' };
return {
request: function (config) {
if (config.url.indexOf('http') > -1 && config.url.indexOf('UpdateDeviceOnlineState') == -1 && config.url.indexOf('maps.googleapis') == -1) {
console.log(config);
//timeout if request takes longer than 15 sec spinner is removed request is cancelled and alert is called
//config.timeout = canceller.promise;
//var time1 = setTimeout(function () {
// canceller.resolve('Unauthorized');
// $rootScope.$broadcast("all_requests_done");
// alert('keine verbindung');
//}, 15000);
numLoadings++;
if (serialRequests == false) {
//if (config.url.indexOf('http') > -1) {
// loadingbar.percent = numLoadings;
// $rootScope.$broadcast("open_requests", loadingbar);
//} else {
// $rootScope.$broadcast("open_requests", loadingspinner);
//}
$rootScope.$broadcast("open_requests", loadingspinner);
} else {
clearTimeout(timeO);
}
}
return config || $q.when(config)
},
response: function (response) {
if (response.config.url.indexOf('http') > -1 && response.config.url.indexOf('UpdateDeviceOnlineState') == -1 && response.config.url.indexOf('maps.googleapis') == -1) {
//clearTimeout(time1);
serialRequests = true;
numLoadings--;
timeO = setTimeout(function () {
serialRequests = false
if ((numLoadings) === 0) {
$rootScope.$broadcast("all_requests_done");
}
});
}
return response || $q.when(response);
},
responseError: function (response) {
if (response.config.url.indexOf('http') > -1 && response.config.url.indexOf('UpdateDeviceOnlineState') == -1 && response.config.url.indexOf('maps.googleapis') == -1) {
serialRequests = true;
numLoadings--;
timeO = setTimeout(function () {
serialRequests = false
if ((numLoadings) === 0) {
$rootScope.$broadcast("all_requests_done");
}
});
}
return $q.reject(response);
}
};
})
But i think you have to work with promises here. $http has a timeout Property, which you can use to prioritize / sort your requests
$http docs for timeout

WinJS Virtualized Data Source + nested asynchronous requests

Hi i'm relatively new to JavaScript and i'm working on a winjs app project where i want to use the Bing image search data source example in my project to virtualize the datasource of a listview.
My problem is understanding how the asynchronous functions work together and how to implement an async xhr request within the existing one.
Currently i'm using a synchronous request but i would like to change that into a asynchronous one.
This is my data adapter:
(function () {
var xxxDataAdapter = WinJS.Class.define(
function (devkey, query, delay) {
this._minPageSize = 2;
this._maxPageSize = 5;
this._maxCount = 50;
this._devkey = devkey;
this._query = query;
this._delay = 0;
},
{
getCount: function () {
var that = this;
var requestStr = 'http://xxx/' + that._query;
return WinJS.xhr({ url: requestStr, type: "GET", /*user: "foo", password: that._devkey,*/ }).then(
function (request) {
var obj = JSON.parse(request.responseText);
if (typeof obj.error === "undefined") {
var count = obj.length;
if (count === 0) { console.log("The search returned 0 results.", "sample", "error"); }
return count;
} else {
console.log("Error fetching results from API", "sample", "error");
return 0;
}
},
function (request) {
if (request && request.name === "Canceled") {
return WinJS.Promise.wrapError(request);
} else {
if (request.status === 401) {
console.log(request.statusText, "sample", "error");
} else {
console.log("Error fetching data from the service. " + request.responseText, "sample", "error");
}
return 0;
}
});
},
itemsFromIndex: function (requestIndex, countBefore, countAfter)
{
var that = this;
if (requestIndex >= that._maxCount) {
return WinJS.Promise.wrapError(new WinJS.ErrorFromName(WinJS.UI.FetchError.doesNotExist));
}
var fetchSize, fetchIndex;
if (countBefore > countAfter) {
//Limit the overlap
countAfter = Math.min(countAfter, 0);
//Bound the request size based on the minimum and maximum sizes
var fetchBefore = Math.max(Math.min(countBefore, that._maxPageSize - (countAfter + 1)), that._minPageSize - (countAfter + 1));
fetchSize = fetchBefore + countAfter + 1;
fetchIndex = requestIndex - fetchBefore;
} else {
countBefore = Math.min(countBefore, 10);
var fetchAfter = Math.max(Math.min(countAfter, that._maxPageSize - (countBefore + 1)), that._minPageSize - (countBefore + 1));
fetchSize = countBefore + fetchAfter + 1;
fetchIndex = requestIndex - countBefore;
}
var requestStr = 'http://xxx/' + that._query;
return WinJS.xhr({ url: requestStr, type: "GET", /*user: "foo", password: that._devkey,*/ }).then(
function (request)
{
var results = [], count;
var obj = JSON.parse(request.responseText);
if (typeof obj.error === "undefined")
{
var items = obj;
for (var i = 0, itemsLength = items.length; i < itemsLength; i++)
{
var dataItem = items[i];
var req = new XMLHttpRequest();
// false = synchronous
req.open("get", "http://xxxxx/" + dataItem.id, false);
req.send();
var jobj = JSON.parse(req.response);
if (typeof jobj.error === "undefined")
{
results.push({
key: (fetchIndex + i).toString(),
data: {
title: jobj.name.normal,
date: Date.jsonFormat(dataItem.calculatedAt, "Do, MMM HH:mm Z"),
result: "",
status: "",
}
});
}
}
return {
items: results, // The array of items
offset: requestIndex - fetchIndex, // The offset into the array for the requested item
};
} else {
console.log(request.statusText, "sample", "error");
return WinJS.Promise.wrapError(new WinJS.ErrorFromName(WinJS.UI.FetchError.doesNotExist));
}
},
function (request)
{
if (request.status === 401) {
console.log(request.statusText, "sample", "error");
} else {
console.log("Error fetching data from the service. " + request.responseText, "sample", "error");
}
return WinJS.Promise.wrapError(new WinJS.ErrorFromName(WinJS.UI.FetchError.noResponse));
}
);
}
});
WinJS.Namespace.define("xxx", {
datasource: WinJS.Class.derive(WinJS.UI.VirtualizedDataSource, function (devkey, query, delay) {
this._baseDataSourceConstructor(new xxxDataAdapter(devkey, query, delay));
})
});
})();
And this is the synchronous request i would like to change to an asynchronous one:
var req = new XMLHttpRequest();
// false = synchronous
req.open("get", "http://xxxxx/" + dataItem.id, false);
req.send();
you can use then function to chain promises. In your scenario, then function need to simple have a if statement.
return WinJS.xhr(params).then(function (req)
{
if (..)
return WinJS.xhr(params2);
else
return; // then function ensures wrapping your sync result in a completed promise
}, function onerror(e)
{
// todo - error handling code e.g. showing a message box based on your app requirement
});
This is what i came up with. Map the json objects received asynchronously and make another asynchronous call for each object to get additional data. Then the nested async calls are joined and returned when all are finished.
return WinJS.xhr({ url: 'http://xxx=' + that._query }).then(function (request) {
var results = [];
var obj = JSON.parse(request.responseText);
var xhrs = obj.map(function (dataItem, index) {
return WinJS.xhr({ url: 'http://xxxx' + dataItem.attrx }).then(
function completed(nestedRequest) {
var xxJobj = JSON.parse(nestedRequest.responseText);
var dataObj = {};
dataObj.title = xxJobj.name;
dataObj.date = Date.jsonFormat(dataItem.attrtrxx, "Do, MMM HH:mm Z");
dataObj.result = "open";
dataObj.status = "foo";
if (dataItem.xx.hasOwnProperty("attrx5")) {
dataObj.opponent = dataItem.attrx4;
} else {
dataObj.opponent = dataItem.attrx3;
}
dataObj.page_title = "xXx";
dataObj.match_id = dataItem.id;
dataObj.type = "largeListIconTextItem";
dataObj.bg_image = "http://xxx/" + xxJobj.attrx2 + "-portrait.jpg";
results.push({
key: (fetchIndex + index).toString(),
data: dataObj
});
},
function (err) {
console.log(err.status);
console.log(err.responseText);
}
);
});
return WinJS.Promise.join(xhrs).then(
function (promises) {
return {
items: results, // The array of items
offset: requestIndex - fetchIndex, // The offset into the array for the requested item
};
},
function (err) {
console.log(JSON.stringify(err));
}
);
});

Categories