How to fill an Array with response of an http request? - javascript

I want to fill a JavaScript array with a few objects, caught by an http request. Unfortunatly I don't know which ArrayMethod I should use. I tried splice(), but it seems like it doesn't accept variables (for the http output) as an input. Is there anybody who has some tips or knows how to do it?
In my code example I want to fill the Array with the content, shown in "id01".
Thanks for your help!
<html>
<body>
<div id="id01"></div>
<script>
var xmlhttp = new XMLHttpRequest();
var url = "https://waterfallexpress2020.s3.eu-central-1.amazonaws.com/myTutorial.txt";
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myArr = JSON.parse(this.responseText);
myFunction(myArr);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
function myFunction(arr) {
var out = "";
var i;
for(i = 0; i < arr.length; i++) {
out += '<a href="' + arr[i].url + '">' +
arr[i].display + '</a><br>';
}
document.getElementById("id01").innerHTML = out;
return out;
}
var test =[];
test.splice(0,0,myFunction); //DOESN'T FILL MY ARRAY WITH THE OUTPUT OF myFunction()
document.write(test);
</script>

You made an asynchronous request, so you will have to wait for response. You did it with the xmlhttp request and the statement myFunction(myArr).
So in order to keep this returning response, you should initiate variable before your request and fill it with the response:
var test;
...
xmlhttp.onreadystatechange = function()
...
test = myFunction(myArr);
...
document.write(test);
Be careful with splice, it create new instance of initial variable and it losts getters and setters.

Related

How Do I Call ETH USD Price Using JAVASCRIPT

I intend to print the USD value of ETH from
"https://api.coinmarketcap.com/v1/ticker/ethereum/"
using JavaScript. However, when I include the script
<script type="text/javascript">
var xmlhttp = new XMLHttpRequest();
var url = "";
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var json = JSON.parse(this.responseText);
parseJson(json);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
function parseJson(json) {
var time = "<b>Last Updated : " + json["time"]["updated"] + "</b>";
var usdValue = "$" + json["eth"]["price.usd"]["rate"];
document.getElementById("data").innerHTML =
usdValue
}
</script>
in my HTML file, along with other scripts of other Price APIs, the code above returns nothing. What am I doing wrong? I need help please.
Try Something like this
<body>
<div id="data" />
<script type="text/javascript">
var json = new XMLHttpRequest(); // start a new variable to store the JSON in
json.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) { // if HTTP header 200 - ok
var object = JSON.parse(this.responseText); // set the variable 'object' to whatever we get back, in our case it is an array of 10 different arrays
for(var i=0;i<object.length;i++){ // looping through json
var item = object[i];
if(item["symbol"] === "ETH"){ // finding when symbol is ETH
var usdValue = "$" + item["price_usd"]; // Fetching price_usd value
document.getElementById("data").innerHTML = usdValue;
}
}
}
};
json.open(
"GET", // method
"https://api.coinmarketcap.com/v1/ticker/ethereum/", // url
true // async
); // initialise the request
json.send(); //send request
</script>
</body>
Run the code snippet
According https://api.coinmarketcap.com/v1/ticker/ethereum/, the return value of JSON.parse(this.responseText) will be a json array. So pass json[0] to your parseJson().
The parsed json doesn't have field/property of 'time' or 'eth'. I suggest you use following code to get what you want.
let time = `<b>Last Updated : ${new Date(parseInt(json['last_updated'])).toDateString()}</b>`;
let usdValue = `\$${json['price_usd']}`;

An AJAX call with JavaScript

I'm trying to learn how to make an AJAX call using vanilla JavaScript in an effort to move away from JQuery for a little project that I'm working on but don't seem to be getting past xmlhttp.onreadystatechange. Can anyone point to what I'm doing wrong (the function getDVDsAndBluRays() is getting invoked on DOMContentLoaded)? Thanks!
function getDVDsAndBluRays() {
console.log("Getting logged");
var xmlhttp = new XMLHttpRequest();
var url = 'http://www.omdbapi.com/?t=metropolis&y=&plot=short&r=json';
xmlhttp.onreadystatechange = function() {
console.log("Not getting logged");
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
console.log('responseText:' + xmlhttp.responseText);
var myMovies = JSON.parse(xmlhttp.responseText);
myFunction(myMovies);
}
xmlhttp.open('GET', url, true);
xmlhttp.send();
};
}
function myFunction(myMovies) {
for (var i = 0; i < myMovies.length; i++) {
var title = myMovies[i].Title.toLowerCase().split(' ').join('+');
var year = myMovies[i].Year;
console.log(title + ", " + "year");
}
}
It should be like that, notice the location of open and send functions:
function getDVDsAndBluRays() {
console.log("Getting logged");
var xmlhttp = new XMLHttpRequest();
var url = 'http://www.omdbapi.com/?t=metropolis&y=&plot=short&r=json';
xmlhttp.open('GET', url, true);
xmlhttp.send();
xmlhttp.onreadystatechange = function() {
console.log("Not getting logged");
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
console.log('responseText:' + xmlhttp.responseText);
var myMovies = JSON.parse(xmlhttp.responseText);
myFunction(myMovies);
}
};
}
function myFunction(myMovies) {
for (var i = 0; i < myMovies.length; i++) {
var title = myMovies[i].Title.toLowerCase().split(' ').join('+');
var year = myMovies[i].Year;
console.log(title + ", " + "year");
}
}
onreadystatechange is executed after the call, you were actually "calling the service when it replies"
You have your .open() and .send() inside your onreadystatechange() handler. Put those outside of the onreadystatechange function and you should be good to go.
Onreadystatechange() is the event handler for when there is a change in state in the xmlhttp request, and will not get called until you open the request and send it.
Hope this helped!
You have put the calls to open and send inside the onreadystatechange event handler so they will never be called.
Move them outside it.

How to set multiple HTTP headers in JavaScript get () method

I have been searching the total Internet from around a week and finally decided to post here. I want to send an HTTP get request to an API with two headers for authentication. These are custom headers and need to be sent at once.
I have tried the following code but it never gives me success. The API returns a JSON file which will have parameters like "title", "description". The URL and headers work fine, when I tried it using hurl.it.
This is the code. Please suggest some answer to solve this problem. And one more thing is, I want to do it using JavaScript only, no jQuery, AJAX, or AngularJS.
var xmlhttp = new XMLHttpRequest();
var url = "https://affiliate- api.flipkart.net/affiliate/offers/v1/dotd/json";
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState == 4 &&xmlhttp.status==200) {
var myArr = JSON.parse(xmlhttp.responseText);
function display(arr) {
var i;
var out = " ";
for(i = 0; i < arr.length;i++) {
out += "<p>title:" + arr.dotd[i].title + "<br>description:" + arr.dotd[i].description + "<br></p>";
}
document.getElementById("p1").innerHTML = out;
}
}
else {
alert(xmlhttp.status);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.setRequestHeader("Fk-Affiliate- Token","xxxxxxxxxxxxxxxxx");
xmlhttp.setRequestHeader("Fk-Affiliate-Id","xxxxxxxxx");
xmlhttp.send();

JSON parse error: Cannot read property

I have created some little jt code, but it gives me error
function Mind(){
var request = "request";
var reply = "reply";
var words = '';
this.Reply = function(){
if(request == words.nouns[0].noun){
reply = words.nouns[0].noun;
}
else
reply = this.words.nouns[0].noun;
}
this.SetRequest = function(req){
request = req;
}
this.GetReply = function(){
return reply;
}
this.Parse = function(u){
var xmlhttp = new XMLHttpRequest();
var url = u;
var result;
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
words = JSON.parse(xmlhttp.responseText);
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
return result;
}
this.Construct = function(){
words = this.Parse('mind/words.json');
}}
var mind = new Mind();
mind.Parse('mind/words.json');
and here is my json file
{
"nouns": [
{"noun": "child"},
{"noun": "father"}
]
}
In command live all goes well, but when I run this code, appears error
Uncaught TypeError: Cannot read property 'nouns' of undefined
Mutliple errors. The most fundamental one is that your code ignores that XMLHttpRequest is async, and wont return a value in the same way as "regular" functions. Read about it here: How to make a function wait until a callback has been called using node.js. The TL;DR is that you have to pass in a "callback-function" to your parse-method and "return" your value using that function, instead of using a return-statement. Google for "javascript callbacks" and read a few tutorials if this concept is new to you!
You also have some minor errors, like returning result from Parse, but never actually setting result to anything. Also words is being assigned in multiple places in a way that doesn't really make sense. But both of these things will go away when you solve the sync/async issues.
EDIT:
Essentially the fix looks like this:
this.Parse = function(u, callback){ // this "callback" is new
var xmlhttp = new XMLHttpRequest();
var url = u;
var result;
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
words = JSON.parse(xmlhttp.responseText);
callback(null, words); // we're "returning" the words here
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
// no return statement here!
}
this.Construct = function(){
this.Parse('mind/words.json', function(error, words) {
// here you can use your words!
});
}}

Javascript: XHR not handling multiple async requests

Hi I am trying to access one resource multiple times with with different parameters
In this case requesting
var domains = [
'host1',
'host2'
];
var requests = new Array();
for ( i in domains )
{
requests[i]=new request(domains[i]);
}
function request(site)
{
var url = 'get_remote_status.php?host='+site;
var queues = {};
http_request = new XMLHttpRequest();
http_request.open("GET", url, true, 'username', 'password');
http_request.onreadystatechange = function () {
var done = 4, ok = 200;
if (http_request.readyState == done && http_request.status == ok) {
queues = JSON.parse(http_request.responseText);
var queuesDiv = document.getElementById('queues');
print_queues(queues, queuesDiv, site);
}
};
http_request.send(null);
}
However, only one of of the requests is being handled by the code lambda. Chromium reports that both requests have been received and is viewable in the resourced pane.
Also if I make the request synchronous then it works fine. However this is not acceptable to the release code as a request may timeout.
Thanks
Define http_request using var. Currently, you're assigning the XHR object to a global variable. Because of this, your script can only handle one XHR at a time.
Relevant erroneous code:
function request(site)
{
var url = 'get_remote_status.php?host='+site;
var queues = {};
http_request = new XMLHttpRequest();
Proposed change:
function request(site)
{
var url = 'get_remote_status.php?host='+site;
var queues = {};
var http_request = new XMLHttpRequest(); //VAR VAR VAR !!!
When you omit var before a variable, the variable will be defined in the global (window) scope. If you use var before a variable, the variable is defined within the local scope (in function request, in this case).
In fact it is possible to run multiple async xhr call but you have to give them an unique id as parameter to be able to store and load them locally in your DOM.
For example, you'd like to loop on an array and make a ajax call for each object. It's a little bit tricky but this code works for me.
var xhrarray={};
for (var j=0; j<itemsvals.length; j++){
var labelval=itemsvals[j];
// call ajax list if present.
if(typeof labelval.mkdajaxlink != 'undefined'){
var divlabelvalue = '<div id="' + labelval.mkdid + '_' + item.mkdcck + '" class="mkditemvalue col-xs-12 ' + labelval.mkdclass + '"><div class="mkdlabel">' + labelval.mkdlabel + ' :</div><div id="'+ j +'_link_'+ labelval.mkdid +'" class="mkdvalue">'+labelval.mkdvalue+'</div></div>';
mkdwrapper.find('#' + item.mkdcck + ' .mkdinstadivbody').append(divlabelvalue);
xhrarray['xhr_'+item.mkdcck] = new XMLHttpRequest();
xhrarray['xhr_'+item.mkdcck].uniqueid=''+ j +'_link_'+ labelval.mkdid +'';
console.log(xhrarray['xhr_'+item.mkdcck].uniqueid);
xhrarray['xhr_'+item.mkdcck].open('POST', labelval.mkdajaxlink);
xhrarray['xhr_'+item.mkdcck].send();
console.log('data sent');
xhrarray['xhr_'+item.mkdcck].onreadystatechange=function() {
if (this.readyState == 4) {
console.log(''+this.uniqueid);
document.getElementById(''+this.uniqueid).innerHTML = this.responseText;
}
};
}
}
You have to set each xhr object in a global variable object and define a value xhrarray['xhr_'+item.mkdcck].uniqueid
to get its unique id and load its result where you want.
Hope that will help you in the future.

Categories