What is the correct way to call this API? The api url is: https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd
I tried with this code
<p id="demo">
</p>
<script>
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myObj = JSON.parse(this.responseText);
document.getElementById("demo").innerHTML = myObj.bitcoin;
}
};
xmlhttp.open("GET", "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd" + new Date().getTime(), true);
xmlhttp.send();
</script>
however the value I get is [object Object]. I want to get the value in "usd".
Where am I wrong? Thx
Replaces myObj with myObj.usd but returns null value
The API returns in the form of {"bitcoin":{"usd": -insert value here-}}, so you have to use myObj.bitcoin.usd
You need to access the usd part of the object when you set the innerHTML as #SuspenseFallback mentioned.
You also need to remove the + new Date().getTime() part from your URL string. I don't see a date part in the API docs for the price endpoint.
you should use the fetch method. the better and the modern way of calling API using native javascript.
There is no problem with the way you did it but there are a few things that you can do with fetch and not with XHR.
you can read more about fetch by this link: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
there is an example of using fetch:
fetch(
"https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd"
)
.then((response) => response.json())
.then((data) => {
console.log(data);
});
or you can use async-await to achieve the same result :
(async () => {
const response = await fetch(
"https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd"
);
const data = await response.json();
console.log(data);
})();
note: I have used Javascript Self Invoking Functions which is a
function that calls itself.
The answers quickly resolve the issue, however I ran into another problem where there are hyphenated words.
Sample API:
https://api.coingecko.com/api/v3/simple/price?ids=bitcoin-cash&vs_currencies=usd
Related
Preface: I'm a novice at JS, have no formal training in it, and usually make things on the fly by researching what I am trying to do. That failed this time.
I am currently trying to make a short JS script that will serve as a bookmarklet. The intent is to leverage the Tinder API to show users of Tinder some of the profile pictures of users who liked them, normally available with the Gold Feature.
Currently, it looks like this:
var stringz;
var xhr = new XMLHttpRequest();
var tokez = localStorage.getItem("TinderWeb/APIToken");
var url = "https://api.gotinder.com/v2/fast-match/teasers?locale=en";
xhr.withCredentials = true;
xhr.open("GET", url);
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("content-type", "application/json; charset=utf-8");
xhr.setRequestHeader("x-auth-token", tokez);
xhr.setRequestHeader("tinder-version", "2.35.0");
xhr.setRequestHeader("platform", "web");
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
stringz = xhr.responseText;
return stringz;
}
};
//Turn the xhr response into a JSON string
var jasonstring = JSON.parse(stringz);
//Grab the URLs
var jasonstrung = jasonstring.data.results.map(x => x.user.photos.map(y => y.url));
//Turn the URLs into a nicely formatted JSON string
var jason = JSON.stringify(jasonstrung, null, 4);
//See what we got
console.log(jason);
The reason I am doing both JSON.parse and JSON.stringify is that the returned data from the xhr is a text string formatted like JSON but it isn't actually JSON yet so I have to parse it in order to grab the pieces I want, then format them after so they aren't a goopy block (although the stringify part isn't super necessary)
On the first run of this in the Chrome Dev Console, it spits out the following:
VM5418:1 Uncaught SyntaxError: Unexpected token u in JSON at position 0
at JSON.parse (<anonymous>)
at <anonymous>:18:24
My assumption as to why it does this is because stringz is not yet "filled up" and returns as "undefined" when JSON.parse tries to cut through it.
However, once the script completes, if one were to type console.log(stringz), the expected string appears! If one runs the entire script 2x, it prints out the final desired dataset:
[
[
"https://preview.gotinder.com/5ea6601a4a11120100e84f58/original_65b52a4a-e2b2-4fdb-a9e6-cb16cf4f91c6.jpeg"
],
[
"https://preview.gotinder.com/5a4735a12eced0716745c8f1/1080x1080_9b15a72b-10c3-47c6-8680-a9c1ff6bdbf7.jpg"
],
[
"https://preview.gotinder.com/5e8d4231370407010088281b/original_adb4a1e3-06c0-4984-bca1-978200a5a311.jpeg"
],
[
"https://preview.gotinder.com/5ea77de583887d0100f385b8/original_af32971d-6d80-4076-a0f8-92ab54f820b3.jpeg"
],
[
"https://preview.gotinder.com/5bf7a1a29c0764cc3409bb02/1080x1350_c9784773-b937-4564-8c96-1a380832fdab.jpg"
],
[
"https://preview.gotinder.com/5d147c0560364e16004bcf5e/original_bf550230-baba-4d70-8c75-da64a9ce1b6c.jpeg"
],
[
"https://preview.gotinder.com/5c9ca2c2c8a4501600a979aa/original_915f4c0f-eb58-4283-bc58-00fdadc3c33c.jpeg"
],
[
"https://preview.gotinder.com/541efb64f5d81ab67f4b599f/original_7f11dea4-41c8-4e9c-8c7a-0c886484a076.jpeg"
],
[
"https://preview.gotinder.com/5a8b56376c220c1f5d8b43d9/original_7c19a078-8bd7-48f9-8e30-123b8f937814.jpeg"
],
[
"https://preview.gotinder.com/5d0c18341ea6e416002bfb1d/original_41d203ce-d116-4714-a223-90ccfd928ff2.jpeg"
]
]
Is there any way to make this thing work in one go (bookmarklet style)? setTimeout doesn't work unfortunately, assuming it is a problem in terms of taking too long to fill "stringz" before I use JSON.parse on it.
Thank you!
The problem is coming from that XHR makes your function asynchronous: it sends a request and the response arrives later - during that time your next (and next, and next,....) lines of code are executed.
You have to start your JSON string transformation when the response has already arrived - that means you should place your code xhr.onreadystatechange (I had to comment out a lot of things so the snippet works):
var stringz;
var xhr = new XMLHttpRequest();
// var tokez = localStorage.getItem("TinderWeb/APIToken");
// var url = "https://api.gotinder.com/v2/fast-match/teasers?locale=en";
var url = "https://jsonplaceholder.typicode.com/posts";
// xhr.withCredentials = true;
xhr.open("GET", url);
// xhr.setRequestHeader("accept", "application/json");
// xhr.setRequestHeader("content-type", "application/json; charset=utf-8");
// xhr.setRequestHeader("x-auth-token", tokez);
// xhr.setRequestHeader("tinder-version", "2.35.0");
// xhr.setRequestHeader("platform", "web");
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// the response arrives here
stringz = this.responseText;
// start your JSON transformation when the
// response arrives
jsonTransform(stringz)
return stringz;
}
};
xhr.send();
// this part of code will be executed synchronously - this
// doesn't wait until your response arrives
var synchronous = 'this will be logged before response arrives'
console.log(synchronous)
function jsonTransform(stringz) {
//Turn the xhr response into a JSON string
var jasonstring = JSON.parse(stringz);
//Grab the URLs
// var jasonstrung = jasonstring.data.results.map(x => x.user.photos.map(y => y.url));
//Turn the URLs into a nicely formatted JSON string
// var jason = JSON.stringify(jasonstrung, null, 4);
//See what we got
const jason = JSON.stringify(jasonstring)
console.log(jason);
}
Another method
I suggest you use fetch() instead of xhr - with xhr you have to take care of everything - fetch() is quite new, with a Promise based syntax (you'll be meeting that a lot, if you work with APIs)
More on fetch():
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
const url = "https://jsonplaceholder.typicode.com/posts";
// fetch returns a Promise, so you can use
// .then, .catch, .finally - very handy!
fetch(url)
.then(resp => {
return resp.json()
})
.then(json => {
// you have the json formatted response here:
console.log(json)
})
.catch(err => {
console.log(err)
})
You could use fetch() with the friendly async-await syntax, that makes your code feel synchronous:
const url = "https://jsonplaceholder.typicode.com/posts";
// await can only be placed in an async function!
async function fetchAPI(url) {
// try-catch block to handle errors of the fetch()
try {
const response = await fetch(url)
const json = await response.json()
console.log(json)
} catch (err) {
console.log(err)
}
}
fetchAPI(url)
Before I explain what I want to do, here's an MCV of what I'm coding
$("#button").submit(function(event) {
event.preventDefault();
var formData = new FormData(this);
var myString = $('#textarea').val();
var myRegexp = /src="blob:([^'"]+)"/gm;
match = myRegexp.exec(myString);
var inProgress = 0;
while (match != null) {
var xhr = new XMLHttpRequest();
addr = match[1];
xhr.open('GET', 'blob:' + addr, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var myBlob = this.response;
var data = new FormData();
data.append('file', myBlob);
$.ajax({
url: "uploader.php",
type: 'POST',
data: data,
contentType: false,
processData: false,
beforeSend: function() {
inProgress++;
},
success: function(data) {
myString = myString.replace("blob:" + addr, data);
},
error: function() {
// error
},
complete: function() {
--inProgress;
}
});
} else {
// error
}
};
xhr.send();
match = myRegexp.exec(myString);
}
if (!inProgress) {
formData.set('textarea', myString);
submitForm(formData);
}
});
So, I have a text area and it contains an unknown number of BLOB objects. I first try to find these BLOB objects using regexp and then I upload them to the server using a PHP file called uploader.php. Once the file is uploaded, it will return the URL of the uploaded file and I want to replace the BLOB URL by the URL of the uploaded file in the text area and then submit the final content of the textarea to the server for further processing.
It turns out that when I run the code, only the last instance of the regexp is replaced by its uploaded URL. The others remain as they were. I suspect that this is because the while loop does not wait for the ajax requests to be complete. I had a similar problem when trying to submit the form and I solved it by following the suggestions in this answer but I don't know how to fix this issue this time.
Any idea is appreciated
Update: I tried to make ajax work synchronously but my browser said that it was deprecated and it didn't work.
It seems you don't really need it to be synchronous (and I can't see a case when it's better to make an async action look synchronous), but rather only need it to be sequential.
It is possible to make async actions sequential by the use of callbacks (which are rewritable as Promise and in turn rewritable as async/await methods but I'll keep it simple):
// myString is made global for simplicity
var myString;
function uploadBlob(myBlob, addr, callback) {
var data = new FormData();
data.append('file', myBlob);
$.ajax({
url: "uploader.php",
type: 'POST',
data: data,
contentType: false,
processData: false,
success: function(data) {
// file uploaded OK, replace the blob expr by the uploaded file url(data)
myString = myString.replace("blob:" + addr, data);
callback();
},
error: function() {
// error, the uploaded most likely failed, we leave myString alone
// or alternatively replace the blob expr by empty string
// because maybe we dont want to post blob in the final form submit
// uncomment if needed
// myString = myString.replace("blob:" + addr, "");
callback();
}
});
}
function getBlobAndUpload(addr, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'blob:' + addr, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var myBlob = this.response;
uploadBlob(myBlob, addr, callback);
} else {
// error, but callback anyway to continue processing
callback();
}
};
xhr.send();
}
function processAddresses(addresses, callback, current) {
var index = current || 0;
// all addresses processed?
if (index >= addresses.length) {
// yes no more address, call the callback function
callback();
} else {
var addr = addresses[index];
// once the get/upload is done the next address will be processed
getBlobAndUpload(addr, function() {
processAddresses(addresses, callback, index + 1);
});
}
}
$("#button").submit(function(event) {
event.preventDefault();
var formData = new FormData(this);
var addresses = [];
// initialize both localString and myString to the content of the textArea
// localString will be used to extract addresses,
// while myString will be mutated during the upload process
var localString = myString = $('#textarea').val();
var myRegexp = /src="blob:([^'"]+)"/gm;
match = myRegexp.exec(localString);
// collect all addresses first
while (match != null) {
addr = match[1];
addresses.push(addr);
match = myRegexp.exec(localString);
}
// initiate sequential processing of all addresses, and
// pass the callback function triggering the form submit
processAddresses(addresses, function() {
// all the successfully uploaded blob exprs in my string should
// be now replaced by the remote file url now (see commented part
// in upload blob error for a variation of the feature
formData.set('textarea', myString);
submitForm(formData);
});
});
So. I said in comments, that you could use async/await, and gave links. Now I am going to try to teach you how to work with promises and XMLHttpRequest.
So first thing. I would use my own 'library' (not really a library, just 3 new command) called PromiseReq which has XMLHttpsRequest that returns Promises.
You would need two functions from it:
sendToServer(config, data) and getServerFile(config). They do what their names implies.(sendToServer is not so good at the time, but I will improve it sometime later). They just use Promises as returns. They work in very easy way. Code # Github
BUT It was designed for my uses only, so it is not very flexible (although I hope I will improve it sometime).
So we need to learn how to use Promises.
Firstly you need to know what Promise is and why do we use it.
Then you can create one like this:
let pmq = new Promise((res,rej)=>{
// PROMISE BODY HERE
});
Here first warning. Promises made that way don't support return as a way to resolve Promise! You have to use res()!
Some functions just return them (such as fetch()) and we can handle them right after calling function.
Now pmq will be our promise.
You can use pmq.then(callback) to handle what will happen if somewhere in promise body is res() call and pmq.catch(callback) to handle what happens when rej() is called. Remember, that .catch(cb) and .then(cb) returns a Promise, so you can safely chain more than one .then() and at the end add .catch() and it will handle rejection from every one of .then()s.
For example:
pmq = fetch("file.txt");
pmq.then(e=>console.log(e.json())).then(console.log).catch(console.error);
There is a big note there.
The order in which this events will fire.
If for example rP() waits 1s than logs "A" then resolves, this code:
let a = rP();
a.then(_=>console.log("B")).catch(console.error);
console.log("C");
will result in:
C
A
B
Becuase of this there is async/await needed to do this.
To do so you have to make an async function with keyword async.
let fn = async ()=>{}
Here is second thing. Async functions ALWAYS return Promise. And that is the second way you can create a promise. You just don't use res(), rej() only return and throw.
Now we can call inside fn():
let a = await rP().then(_=>console.log("B")).catch(console.error);
console.log("C");
and we will get our
A
B
C
Now. How to use it with XMLHttpRequest?
You need to create new Promise with simple XMLHttpRequest inside:
let xmlp = (type, path,data) => return new Promise((res,req)=>{
let xhr = new XMLHttpsRequest();
xhr.open(type, path, true); // true implies that is it asynchronous call
//...
xhr.send(data);
});
And now when to resolve?
XMLHttpRequest has useful event properties and events. The one that is best for our case is onreadystatechange.
You can use it like so:
xhr.onreadystatechange = _=>{
if(xhr.readyState === 4 && xhr.status === 200) // Everything went smoothly
res(xhr.responseText);
else if(shr.readyState === 4 && xhr.status !== 200) // Something went wrong!
rej(xhr.status);
}
And then to get data you can either
Async/Await
// INSIDE ASYNC FUNCTION
let resData = await xmpl("GET", "path.txt", null).catch(console.error);
.then()
let resData;
xmpl("GET", "path.txt", null).then(r=>{
resData = r;
// REST OF WHOLE FUNCTION TO ENSURE THAT resData HAS BEEN SET
})
.catch(console.error);
You can also send data with xmpl().
xmpl("POST", "observer.php", "Data to send to observer.php!")
.then(whatToDoAfterSendFN);
/*
to get such data in PHP you have to use
$post = file_get_contents('php://input');
*/
I know that this answer is a bit messy and stuff, but I didn't have any idea how to write it :P Sorry.
When I call function CallMe, I get a result from service but my HTML element has text undefined, because of service is still loading data. I try async, await on Test() but no results. I want this to be pure JS. What I do wrong?
CallMe(){
document.getElementById('testId').InnerHTML = Test();
}
function Test(){
var request = new XMLHttpRequest(); // Create a request variable and assign a new XMLHttpRequest object to it.
request.open('GET', 'https://some service'); // Open a new connection, using the GET request on the URL endpoint
request.send();
request.onload = async function () {
var data = await JSON.parse(this.response);
return data[0][0][0];
}
}
function CallMe() {
var request = new XMLHttpRequest(); // Create a request variable and assign a new XMLHttpRequest object to it.
request.open('GET', 'https://some service'); // Open a new connection, using the GET request on the URL endpoint
request.send();
request.onload = async function () {
var data = JSON.parse(this.response);
document.getElementById('testId').InnerHTML = data // depending on your response targert your desired property.
}
}
just do one method and when the call returns a response assign the value to your testId div
Rather than using XMLHttpRequest to make ajax call I recommend using fetch api as it uses Promises, which enables a simpler and cleaner API, avoiding callback hell and having to remember the complex API of XMLHttpRequest. (ref: https://developers.google.com/web/updates/2015/03/introduction-to-fetch).
Using fetch api the your code in pure js will look like below.
fetch('https://some service')
.then( res => res.json() )
.then(response => {
document.getElementById('testId').innerHTML = data[0][0][0];
})
.catch(error => console.error('Error:', error));
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
How can I read this API and get information from it?
to javascript.
https://bitcoinfees.earn.com/api/v1/fees/recommended
this does not seem to work -
loadJSON("https://bitcoinfees.earn.com/api/v1/fees/recommended", gotData, 'jsonp');
function gotData(data) {
println(data);
}
loadJSON is not a native JS function(it is in library p5). You can use the fetch function like this:
fetch("https://bitcoinfees.earn.com/api/v1/fees/recommended") // Call the fetch function passing the url of the API as a parameter
.then((resp) => resp.json()) // Transform the data into json
.then(function(data) {
// Your code for handling the data you get from the API
console.log(data);
console.log(data.fastestFee); //And since it is just an object you can access any value like this
})
.catch(function(err) {
// This is where you run code if the server returns any errors (optional)
console.log(err)
});
Using javascript only:
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
// Typical action to be performed when the document is ready:
document.getElementById("demo").innerHTML = xhttp.responseText;
alert(JSON.stringify(xhttp.responseText));
//To display fastestFee's value
var parseData = JSON.parse(xhttp.responseText);
alert(parseData.fastestFee);
}
};
xhttp.open("GET", "https://bitcoinfees.earn.com/api/v1/fees/recommended", true);
xhttp.send();
<div id="demo"> </div>
First result on Google. Learn it. Use it.
var url = "https://bitcoinfees.earn.com/api/v1/fees/recommended";
var req = $.ajax(url, {
success: function(data) {
console.log(data);
},
error: function() {
console.log('Error!');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I was wondering if there's any ES6 way of getting json or other data from a url.
jQuery GET and Ajax calls are very common but I don't want to use jQuery in this one.
A typical call would look like this:
var root = 'http://jsonplaceholder.typicode.com';
$.ajax({
url: root + '/posts/1',
method: 'GET'
}).then(function(data) {
console.log(data);
});
or without jQuery something like this:
function loadXMLDoc() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE ) {
if (xmlhttp.status == 200) {
document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
}
else if (xmlhttp.status == 400) {
alert('There was an error 400');
}
else {
alert('something else other than 200 was returned');
}
}
};
xmlhttp.open("GET", "ajax_info.txt", true);
xmlhttp.send();
}
My question is...Is there any new ways of doing this ... for example ES6 or is it still the same way?
FETCH API
Example:
// url (required), options (optional)
fetch('https://davidwalsh.name/some/url', {
method: 'get'
}).then(function(response) {
}).catch(function(err) {
// Error :(
});
For more information:
https://developer.mozilla.org/en/docs/Web/API/Fetch_API
Yes there is, using the new Fetch API. Using that you can compess it as much as doing something like:
fetch(url).then(r => r.json())
.then(data => console.log(data))
.catch(e => console.log("Booo"))
However, it's not supported by all browsers yet and not everybody is equally positive about the Fetch API implementation.
Anyhow, you can create your own opinion on that and read up more on it here.
What you want is the Fetch API, but the Fetch API is not a part of ES6 - it just happens to use Promises, which were standardised in ES6.
To get JSON from a URL with the Fetch API:
window.fetch('/path/to.json')
.then(function(response){
return response.json();
}).then(function(json){
return doSomethingWith(json);
});
If you need to support browsers which don’t have the Fetch API, Github has open sourced a polyfill.
Here is another method using axios which is a Promise based HTTP client for the browser and node.js.
Installation:
npm install --save axios
or
yarn add axios
Then, in your project file:
import axios from 'axios'
const data = axios.get('/path/to/your/data.json')