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']}`;
Related
Before I start, here is the API. Super simple: https://www.cryptonator.com/api
To note, I have worked with api before, but i used a await async function, but for some reason I couldn't get that to work....but I found a tutorial for doing this with XML http request, so I decided to just move forwards doing it in XML because I was able to make a simple Bitcoin ticker.
I am building a simple widget to display the prices of Bitcoin, Litecoin, and Ethereum using the cryptonator API. Like I said above, I made a bitcoin ticker with the first function ( see code below ), and it works great. However, I am having issues trying to get 3 different currencies.
Here is what I am trying to do.
var url = "https://api.cryptonator.com/api/ticker/btc-usd";
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 usdValue = json["ticker"]["price"];
document.getElementById("data").innerHTML = usdValue;
var usdValue = usdValue.replace(/[^\d.\-]/g, "");
var usd = parseFloat(usdValue);
document.getElementById("data").innerHTML = "$ " + usd.toFixed(2);
}
//
//
var xmlhttp2 = new XMLHttpRequest();
var url2 = "https://api.cryptonator.com/api/ticker/ltc-usd";
xmlhttp2.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var json = JSON.parse(this.responseText);
parseJson(json);
}
};
xmlhttp2.open("GET", url2, true);
xmlhttp2.send();
function parseJson(json) {
var LTCusdValue = json["ticker"]["price"];
// document.getElementById("data2").innerHTML = LTCusdValue;
var LTCusdValue = LTCusdValue.replace(/[^\d.\-]/g, "");
var LTCusd = parseFloat(LTCusdValue);
document.getElementById("data2").innerHTML = "$ " + LTCusd.toFixed(2);
}
//
//
//
var xmlhttp3 = new XMLHttpRequest();
var url3 = "https://api.cryptonator.com/api/ticker/eth-usd";
xmlhttp3.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var json = JSON.parse(this.responseText);
parseJson(json);
}
};
xmlhttp3.open("GET", url3, true);
xmlhttp3.send();
function parseJson(json) {
var ETHusdValue = json["ticker"]["price"];
// document.getElementById("data3").innerHTML = ETHusdValue;
var ETHusdValue = ETHusdValue.replace(/[^\d.\-]/g, "");
var ETHusd = parseFloat(ETHusdValue);
document.getElementById("data3").innerHTML = "$ " + ETHusd.toFixed(2);
}
As you can see, I am trying to make 3 request to 3 different APis, but it isn't working. If I comment out all but one of these functions, it works fine. My issues comes when i try to use all 3 at once. If i use Bitcoin and Litecoin only, it will actually work, but will just break again once I try to use the 3rd function ( to get ethereum price ).
The parseJson function is defined three times. This means that every time you write the function it will overwrite the previous definition. So in your case only the last parseJson function will be used for all three requests. You could do a couple of things.
Write three different variations. (Bad practice)
Though this would be the less favorable of the options. It will require you to have repeated code copied multiple times. This can be done more efficiently.
function parseJson1(json) {
...
}
function parseJson2(json) {
...
}
function parseJson3(json) {
...
}
Add an argument to the function. (Good practice)
Give the parseJson function a second argument that selects the element to output the value. This should be the id of the element you'll want to select.
This is the better solution because it only requires you to write a function once and call it multiple times accounting for the variations.
function parseJson(json, id) {
var output = document.getElementById(id); // Select the element based on the id.
if (output === null) { // If element is not found, stop the function.
return;
}
var price = json["ticker"]["price"];
var usdValue = price.replace(/[^\d.\-]/g, "");
var usd = parseFloat(usdValue);
output.innerHTML = "$ " + usd.toFixed(2);
}
The last technique is applicable to the rest of your code. Be aware of repeating yourself. You'll write much cleaner and better code when you only have to write something once.
If I understood you well you can create a method for all cryptos and avoid repeting the same code. If you run the example below you will be able to see all cryptos and also it's easy to add new ones:
const URL = 'https://api.cryptonator.com/api/ticker/'
const cryptos = ['btc', 'ltc', 'eth']
cryptos.map(crypto => {
fetch(`${URL}${crypto}-usd`)
.then(data => data.json())
.then(({ ticker: { base, price } }) => console.log(`${base}: ${(+price).toFixed(2)}`))
})
We are using fetch that is modern XHR. Hope this help.
You should be able to write an async wrapper function for this using a Promise.. This will allow you to use async/await with XHR..
To make using XHR a lot easier, you can use the built in fetch API.. According to this, most browsers support fetch.. All in all, I prefer using fetch over axios, XHR, etc.. but since you specifically asked about XHR, that is how I answered.
If you did not want to await each response, you can do something like this:
// basic XHR wrapper function for 'get'
function getXHR(url) {
return new Promise(function(resolve, reject) {
const xhr = new XMLHttpRequest();
xhr.open("get", url, true);
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
this.status == 200
? resolve(this.responseText)
: reject(this.status);
}
};
xhr.send();
});
}
const ethElement = document.getElementById("eth");
const bcElement = document.getElementById("bc");
const lcElement = document.getElementById("lc");
// etherium
getXHR("https://api.cryptonator.com/api/ticker/eth-usd")
.then(eth => {
// Can turn into JSON like this:
//const ethJson = JSON.parse(eth);
ethElement.innerHTML = eth;
})
// bitcoin
getXHR("https://api.cryptonator.com/api/ticker/btc-usd")
.then(bc => {
// Can turn into JSON like this:
//const bcJson = JSON.parse(bc);
bcElement.innerHTML = bc;
})
// litecoin
getXHR("https://api.cryptonator.com/api/ticker/ltc-usd")
.then(lc => {
// Can turn into JSON like this:
//const lcJson = JSON.parse(lc);
lcElement.innerHTML = lc;
})
<h1>eth:</h1>
<pre id="eth"></pre>
<h1>bc:</h1>
<pre id="bc"></pre>
<h1>litecoin:</h1>
<pre id="lc"></pre>
I have created the following demo to show you how to accomplish this using async/await:
Init(); // call 'main' function
// basic XHR wrapper function for 'get'
function getXHR(url) {
return new Promise(function(resolve, reject) {
const xhr = new XMLHttpRequest();
xhr.open("get", url, true);
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
this.status == 200
? resolve(this.responseText)
: reject(this.status);
}
};
xhr.send();
});
}
// "Main" function
async function Init() {
const ethElement = document.getElementById("eth");
const bcElement = document.getElementById("bc");
const lcElement = document.getElementById("lc");
// etherium
const eth = await getXHR("https://api.cryptonator.com/api/ticker/eth-usd");
const ethJson = JSON.parse(eth);
ethElement.innerHTML = ethJson.ticker.price + " " + ethJson.ticker.target;
// bitcoin
const bc = await getXHR("https://api.cryptonator.com/api/ticker/btc-usd");
const bcJson = JSON.parse(bc);
bcElement.innerHTML = bcJson.ticker.price + " " + bcJson.ticker.target;
// litecoin
const lc = await getXHR("https://api.cryptonator.com/api/ticker/ltc-usd");
const lcJson = JSON.parse(lc);
lcElement.innerHTML = lcJson.ticker.price + " " + lcJson.ticker.target;
}
div h1,
div p {
display: inline;
vertical-align: top;
font-family: 'Open Sans', sans-serif;
line-height: 38px;
}
<div>
<h1>eth:</h1>
<p id="eth"></p>
</div>
<div>
<h1>btc:</h1>
<p id="bc"></p>
</div>
<div>
<h1>ltc:</h1>
<p id="lc"></p>
</div>
I am trying to learn the ins and outs of using APIs and this is my first attempt. I am able to get the data from the api but when I try to display it on the webpage via a forEach loop the console says that the forEach property is undefined. How can I fix this?
document.querySelector('.get-player').addEventListener('click', getPlayers);
function getPlayers(e) {
let request;
const input1 = document.querySelector('input[type="text"]').value;
const api = 'https://www.balldontlie.io/api/v1/players?search=';
let sum = api + input1;
request = new XMLHttpRequest();
request.open('GET', sum, true);
request.onload = function() {
let info = JSON.parse(this.response);
let output = '';
if (request.status >= 200 && request.status < 400) {
console.log(info);
info.value.forEach(function(data) {
output += `<li>${data.position}</li>`;
});
} else {
console.log(input1.value);
}
document.querySelector('.position').innerHTML = output;
}
request.send();
e.preventDefault();
}
The error message is actually quite clear*:
TypeError: info.value is undefined
Your info object does not have a value property, as you can see in the console. You'll probably want to iterate .data instead:
document.querySelector('.get-player').addEventListener('click', getPlayers);
function getPlayers(e) {
let request;
const input1 = document.querySelector('input[type="text"]').value;
const api = 'https://www.balldontlie.io/api/v1/players?search=';
let sum = api + input1;
request = new XMLHttpRequest();
request.open('GET', sum, true);
request.onload = function() {
let info = JSON.parse(this.response);
//console.log(info);
let output = '';
if (request.status >= 200 && request.status < 400) {
info.data.forEach(function(data) {
output += `<li>${data.position}</li>`;
});
} else {
console.log(input1.value);
}
document.querySelector('.position').innerHTML = output;
}
request.send();
e.preventDefault();
}
<input type="text" />
<button class="get-player">get player</button>
<ul class="position"></ul>
*at least that's what I got running your code. If it actually said something different about forEach being undefined, then there's something differing between the code you provided and your actual production code.
I went through your code, you were trying to iterate through info.value but info does not have a key called value, the correct key was data. I have corrected your code at the relevant place:
forEach is an array method, trying to use it on an undefined value will throw an error.
Read more about forEach: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
document.querySelector('.get-player').addEventListener('click', getPlayers);
function getPlayers(e) {
let request;
const input1 = document.querySelector('input[type="text"]').value;
const api = 'https://www.balldontlie.io/api/v1/players?search=';
let sum = api + input1;
request = new XMLHttpRequest();
request.open('GET', sum, true);
request.onload = function() {
let info = JSON.parse(this.response);
let output = '';
if (request.status >= 200 && request.status < 400) {
console.log(info);
info.data.forEach(function(data) { //REPLACE VALUE BY DATA
output += `<li>${data.position}</li>`;
});
} else {
console.log(input1.value);
}
document.querySelector('.position').innerHTML = output;
}
request.send();
e.preventDefault();
}
actually you are accessing wrong key from info object
actual response contains array named data
and you are accessing value which is undefined hence can't be iterated.
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.
Hey everybody I have a problem.
I am building a website and I want to fetch data from two different xml files with two different functions.
ShowResult is used to get a game score and the name of a specific user.
GiveFeedback also needs the score from the first function to fetch a fitting feedback about this score from a different xml file.
I don´t get an error Message. My only problem is that the second function (giveFeedback) isn´t able to fetch data from the xml because it needs a variable (score) from the first function (showResults). Both functions work on their own but I am unable to “transfer” the score data from showResults to giveFeedback.
How can I transfer the score data to the function GiveFeedback or is there a better way to resolve this problem?
Thanks!
i tried some solutions (global variable, inserting the first function in the second,..) which were already posted but unfortunately i didn´t managed to get it running.
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
showResult(xhttp.responseXML);
}
};
xhttp.open("GET", "user.xml", true);
xhttp.send();
function showResult(xml) {
var name = "";
var score = "";
path1 = "/userdb/user/name";
path2 = "/userdb/user/score";
var nodes = xml.evaluate(path1, xml, null, XPathResult.ANY_TYPE, null); var result = nodes.iterateNext();
name = result.childNodes[0].nodeValue;
var nodes = xml.evaluate(path2, xml, null, XPathResult.ANY_TYPE, null); var result = nodes.iterateNext();
//Thats wehere the variable (score) is, which i need for the second function (giveFeedback)
score = result.childNodes[0].nodeValue;
document.getElementById("user").innerHTML = "Congratulations " + name + ", you made " + score;
}
var xhttp2 = new XMLHttpRequest();
xhttp2.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
givefeedback(xhttp2.responseXML);
}
};
xhttp2.open("GET", "feedback.xml", true);
xhttp2.send();
function givefeedback(xml) {
var feedback = "";
// This is where it´s needed
if (score > 1){
path = "/feedback/congratulations[percentage=25]/text";
}
else if (score > 8){
path = "/feedback/congratulations[percentage=50]/text";
}
var nod = xml.evaluate(path, xml, null, XPathResult.ANY_TYPE, null);
var res = nod.iterateNext();
feedback = res.childNodes[0].nodeValue;
document.getElementById("feedback").innerHTML = feedback;
}
</script>
i managed to resolve my problem.
first of all i had to declare a global variable outside the functions.
Then i had to convert the fetched variable (score) to a Number.
I am using the following code to check my database for login information and receive it back inside the application but I am having the issue that I cannot parse the JSON information. I have parsed it into an array and when I run the following code the console returns:
I am wondering how do I take this a step further and read the number for "loggedin" and get the "username" also. I have tried replacing myArr with myArr[0].loggedin or even with myArr[0] but then I get a return of undefined.
Anyone any suggestions?
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('loginForm').addEventListener('submit', function() {
var usernameTest = document.getElementById('username').value;
var passwordTest = document.getElementById('username').value;
//alert("username is: " + usernameTest);
//console.log("password is: " + passwordTest);
//alert("test");
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert(this.responseText);
var myArr = JSON.parse(this.responseText);
chrome.extension.getBackgroundPage().console.log(myArr);
}
};
request.open('GET', 'http://localhost/api/login.php?username='+usernameTest+'&password='+passwordTest);
request.send();
});
});
What worked for me after GaetanoM's comment is:
myArr.UAPlugin[0].loggedin or myArr.UAPlugin[0].username