Js code does not run sequentially due to asynchronous [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
EDIT: My js code involve asynchronous, so that it actually finishes the second alert() in the ready method before the init() finish executing. Any idea on how to make sure that my second alert() executes after the init()? Thank you in advance.
var notes = [];
$(document).ready(function() {
//var notes = [];
alert("before " + notes.length);
init();
alert("after " + notes.length)
//execute(notes, 0);
});
function init() {
loadJSON(function(response) {
// Parse JSON string into object
var actual_JSON = JSON.parse(response);
var len = actual_JSON.notes.length;
//alert("length is " + len);
for(var i = 0; i < 6; i++) {
notes.push(actual_JSON.notes[i]);
}
//alert("after for loop " + notes.length);
});
}
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'test.json', true);
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
callback(xobj.responseText);
}
};
xobj.send(null);
}

Use promise
var notes = [];
$(document).ready(function() {
alert("before " + notes.length);
init()
.then(function(){
alert("after " + notes.length)
})
.catch(function(err){
console.log('error in init()', err)
});
});
function init() {
return new Promise(function(resolve, reject) {
loadJSON(function(response) {
var actual_JSON = JSON.parse(response);
var len = actual_JSON.notes.length;
for(var i = 0; i < 6; i++) {
notes.push(actual_JSON.notes[i]);
}
resolve()
});
});
}
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'test.json', true);
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
callback(xobj.responseText);
}
};
xobj.send(null);

Related

Console.log() does not await in async function [duplicate]

This question already has answers here:
In JavaScript how do I/should I use async/await with XMLHttpRequest?
(5 answers)
How do I convert an existing callback API to promises?
(24 answers)
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
I'm trying to get the exchange rates to calculate approximate prices in dollars.
I want to get result in console.log(currency), but I just got undefined over an over
Pls help)
(async function() {
let date = new Date();
let currency = await searchCurrency();
await console.log(currency) // result expected
})();
function searchCurrency(){
if(!localStorage.currency||!JSON.parse(localStorage.currency).date==date.getDate()+'.'+date.getMonth())
{
return getCurrency(date);
} else {
console.log('LS the same!')
return JSON.parse(localStorage.currency).val;
}
}
function getCurrency(date){
var answer;
var xhr = new XMLHttpRequest();
var apiKey = "my_key";
var query = 'RUB' + "_" + 'USD';
var url =
"https://free.currconv.com/api/v7/convert?q=" +
query +
"&compact=ultra&apiKey=" +
apiKey;
xhr.open("GET", url);
xhr.onload = function () {
if (xhr.status != 200) {
console.log(`Error ${xhr.status}: ${xhr.statusText}`);
answer = 80;
} else {
console.log(`${xhr.response}`);
localStorage.setItem('currency', JSON.stringify({val: JSON.parse(xhr.response)[query], date: date.getDate()+'.'+date.getMonth()}));
answer = JSON.parse(xhr.response)[query];
}
};
xhr.send();
return answer;
}
UPD: Thanks for comments and similar questions. I wrapped my request function in a promise like below and it's working now :) Posting that here if it'll be useful for someone in future.
(async function() {
let date = new Date();
let currency;
if (localStorage.currency&&JSON.parse(localStorage.currency).date==date.getDate()+'.'+date.getMonth()){
currency = JSON.parse(localStorage.getItem('currency')).val;
} else {
currency = await makeRequest(date);
localStorage.setItem('currency', JSON.stringify({val: currency, date: date.getDate()+'.'+date.getMonth()}))
}
await console.log(currency);
})();
function makeRequest(date) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest();
xhr.open('GET', 'https://free.currconv.com/api/v7/convert?q=RUB_USD&compact=ultra&apiKey='secret_api_key');
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(JSON.parse(xhr.response).RUB_USD);
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
xhr.send();
});
}

(beginner javascript) get multiple text files xml request

Very grateful if someone can help me out with the syntax here- I am hoping to make several XML requests, each time getting a different text file. Here is the general structure of my code. How can I get each file in turn (f0, f1 and f2)?
window.onload = function(){
var f = (function(){
var xhr = [];
for (i = 0; i < 3; i++){
(function (i){
xhr[i] = new XMLHttpRequest();
f0 = "0.txt"
f1 = "1.txt"
f2 = "2.txt"
//??? xhr[i].open("GET", file i, true);
xhr[i].onreadystatechange = function () {
if (xhr[i].readyState == 4 && xhr[i].status == 200) {
//do stuff
}
};
xhr[i].send();
})(i);
}
})();
};
Simply put your filenames in an array.
window.onload = function(){
var f = (function(){
var xhr = [];
var files = ["f0.txt", "f1.txt", "f2.txt"];
for (i = 0; i < 3; i++){
(function (i){
xhr[i] = new XMLHttpRequest();
xhr[i].open("GET", files[i], true);
xhr[i].onreadystatechange = function () {
if (xhr[i].readyState == 4 && xhr[i].status == 200) {
//do stuff
}
};
xhr[i].send();
})(i);
}
})();
};
Something like this should work
// ...
for (i = 0; i < 3; i++){
(function (i){
xhr[i] = new XMLHttpRequest();
xhr[i].open('GET', i.toString() + '.txt'); // <-- this line
xhr[i].onreadystatechange = function () {
if (xhr[i].readyState == 4 && xhr[i].status == 200) {
// ....

Javascript call function after multiple XMLHttpRequests

I have some divs that I replace with new html. So far so good.
(function() {
var obj = function(div) {
var obj = {};
obj.divToReplace = div;
obj.objId = obj.divToReplace.dataset.id;
obj.template = "<div class="newDivs"><p>#Name</p><img src='#ImageUrl'/></div>";
obj.replaceDiv = function() {
var xhr = new XMLHttpRequest();
xhr.open( 'GET', encodeURI('http://.../' + obj.objId) );
xhr.onload = function(e) {
if (xhr.status === 200) {
var x = JSON.parse(xhr.responseText).data.attributes;
var newHtml = obj.template
.replaceAll("#Name", x.name)
.replaceAll("#ImageUrl", x.imageUrl);
obj.divToReplace.outerHTML = newHtml;
}
else {
console.log(xhr.status);
}
};
xhr.send();
};
return {
replaceDiv: obj.replaceDiv
}
};
String.prototype.replaceAll = function(search, replace)
{
return this.replace(new RegExp(search, 'g'), replace);
};
//get the elements I want to replace
var elems = document.getElementsByClassName('divToReplace');
//replace them
for (i = 0; i < elems.length; i++) {
obj(elems[i]).replaceDiv();
}
//call handleStuff ?
})();
Then I want to add addEventListener to the divs, and it's here I get stuck. I want to call handleStuff() after all the divs are replaced. (Because of course, before I replace them the new divs don't exists.) And I can't use jQuery.
var handleStuff = function(){
var classname = document.getElementsByClassName("newDivs");
var myFunction = function() {
};
for (var i = 0; i < classname.length; i++) {
classname[i].addEventListener('click', myFunction, false);
}
...............
How can I add a callback that tells me when all the divs are replaced? Or is it overall not a good solution for what I'm trying to do?
Sorry for using jQuery previously, here is solution with native Promise(tested)
(function() {
var f = {
send : function(){
var promise = new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.open( 'GET', encodeURI('http://www.google.com/') );
xhr.onload = function(e) {
if (xhr.status === 200) {
//your code
resolve();
console.log('resolve');
} else {
console.log(xhr.status);
}
};
xhr.send();
});
return promise;
}
}
var promises = [];
for (i = 0; i < 100; i++) {
promises.push(f.send());
}
Promise.all(promises).then(function(){
console.log('success');
});
})();

Ajax in for loop without jquery [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
I have a for loop that call a ajax method
function viderTableauConteneur()
{
var caf = document.getElementById('CAF').value;
var tabConteneurAjouter = caf.split("#");
for (var i = 0; i < tabConteneurAjouter.length; i++) {
if(!verifierConteneurAppartienClient(tabConteneurAjouter[i]));
removeConteneur(tabConteneurAjouter[i]);
};
}
function verifierConteneurAppartienClient(serialNumber)
{
var e = document.getElementById("id_client");
var idClient = e.options[e.selectedIndex].value;
var xhr = getXhr();
var res = 12;
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4 && xhr.status == 200)
{
if(xhr.responseText == "0")
return false;
else if(xhr.responseText == "1")
return true;
}
}
xhr.open("GET","index.php?option=com_tkcontrack&controller=facture&task=verifierConteneurAppartienClient&refConteneur="+serialNumber+"&id_client="+idClient,true);
xhr.send();
}
Well if I alert the xhr.responseText I got "1", but when I alert the result in the viderTableauConteneur method I always got "Undifined"
Any help please
You could modify your code this way :
function viderTableauConteneur()
{
var caf = document.getElementById('CAF').value;
var tabConteneurAjouter = caf.split("#");
for (var i = 0; i < tabConteneurAjouter.length; i++) {
verifierConteneurAppartienClient(tabConteneurAjouter[i],
function()
{
alert('true');
},
function()
{
alert('false');
removeConteneur(tabConteneurAjouter[i])
}
);
}
}
/* callbcakIfTrue and callbackIfFalse have to be 2 functions
that will be called respectiveley if the return of the
ajax call is true or false.
*/
function verifierConteneurAppartienClient(serialNumber, callbackIfTrue, callbackIfFalse)
{
var e = document.getElementById("id_client");
var idClient = e.options[e.selectedIndex].value;
var xhr = getXhr();
var res = 12;
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4 && xhr.status == 200)
{
if(xhr.responseText == "1")
callbackIfTrue();
else
callbackIfFalse();
}
}
xhr.open("GET","index.php?option=com_tkcontrack&controller=facture&task=verifierConteneurAppartienClient&refConteneur="+serialNumber+"&id_client="+idClient,true);
xhr.send();
}

Ajax without jQuery [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to make an ajax call without jquery?
I have code in js(Ajax) but I want to make it without Ajax(XMLHttpRequest)
$.ajax({
type:'POST',
data:'slug='+prize,
url:'/wybrana-nagroda/',
success:function(msg)
{
$('#whaiting').hide();
if(msg==='winner')
$(window.location).attr('href','/formularz');
}
});
How it should look?
function send(post, url) {
var client = new XMLHttpRequest();
client.open("POST", url);
client.send(message);
}
?
Thanks.
If you want it to be compatible on all browsers, you'll need to do something like the following:
function sendRequest(url,callback,postData) {
var req = createXMLHTTPObject();
if (!req) return;
var method = (postData) ? "POST" : "GET";
req.open(method,url,true);
req.setRequestHeader('User-Agent','XMLHTTP/1.0');
if (postData)
req.setRequestHeader('Content-type','application/x-www-form-urlencoded');
req.onreadystatechange = function () {
if (req.readyState != 4) return;
if (req.status != 200 && req.status != 304) {
// alert('HTTP error ' + req.status);
return;
}
callback(req);
}
if (req.readyState == 4) return;
req.send(postData);
}
var XMLHttpFactories = [
function () {return new XMLHttpRequest()},
function () {return new ActiveXObject("Msxml2.XMLHTTP")},
function () {return new ActiveXObject("Msxml3.XMLHTTP")},
function () {return new ActiveXObject("Microsoft.XMLHTTP")}
];
function createXMLHTTPObject() {
var xmlhttp = false;
for (var i=0;i<XMLHttpFactories.length;i++) {
try {
xmlhttp = XMLHttpFactories[i]();
}
catch (e) {
continue;
}
break;
}
return xmlhttp;
}
Credit: quirksmode

Categories

Resources