Trying to get my code to connect to API and retrieve a list of local farmers markets but keep getting Reference error that xmlhttp is not defined on line 40. Haven't caught any spelling errors and have tried moving chunks of code to see if they work at different positions.
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8">
<title>Markets</title>
<script>
window.onload = function() {
function myFunction(arr) {
out = "<h1>Markets</h1>";
var i;
for (i = 0; i < array.results.length; i++) {
out = out + "<em>" + item.marketname + "</em><br>" + details.marketdetails.Address + "</p>"
arr.results.forEach(printDetails)
}
document.getElementById("market_details").innerHTML = out;
}
var mybutton = document.getElementById("submit_btn")
mybutton.onclick = function() {
var xmlhttp = new XMLHttpRequest();
var zip = document.getElementById("zip").value
var url = "http://search.ams.usda.gov/farmersmarkets/v1/data.svc/zipSearch?zip=" + zip;
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myArr = JSON.parse(xmlhttp.responseText);
myFunction(myArr);
}
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
itemsProcessed = 0
function printDetails(item, index, array) {
console.log(item.marketname)
var xmlhttp = new XMLHttpRequest();
var url2 = "http://search.ams.usda.gov/farmersmarkets/v1/data.svc/mktDetail?id=" + id;
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myDArr = JSON.parse(xmlhttp.responseText);
details = myDArr
//console.log(myDArr.marketdetails)
};
xmlhttp.open("GET", url2, true);
xmlhttp.send();
itemsProcessed++
}
}
</script>
</head>
<body>
<h1> Find Your Local Market!<h1>
Enter Zip Code:<input id="zip"></p><br>
<button id = "submit_btn">Submit</button>
<div id="market_details"></div>
</body>
The first problem is that you define the xmlhttp inside the onclick handler and you use it outside the handler:
mybutton.onclick = function() {
var xmlhttp = new XMLHttpRequest(); //<-- This must be used from inside the current function
//Your code here
xmlhttp.open("GET", url, true); //<-- put this inside the function
xmlhttp.send(); //<-- put this inside the function
}
The second problem is that you open and send the XMLHttpRequest inside the onreadystatechange handler:
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myDArr = JSON.parse(xmlhttp.responseText);
details = myDArr
//console.log(myDArr.marketdetails)
};
itemsProcessed++
}
xmlhttp.open("GET", url2, true);//<-- put this outside the onreadystatechange handler
xmlhttp.send();//<-- put this outside the onreadystatechange handler
I hope this will help you.
Related
Im trying to combine open data with 2 http-requests. I need to use one value of the first response, to make the second request-url (the value is part of the second url). How can i do that?
here is my code:
https://codepen.io/1234cb/pen/wvBGKze
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<h3>XMLHttpRequest</h3>
zipcode <input type="text" id="zip" value="3136jr" title="zipcode"><br><br>
housnr <input type="text" id="housenr" value="77" title="housenr"><br><br>
<button type="button" onclick="loadDoc();loadDoc2()">Get Content</button>
<p id="demo">response 1</p>
<p id="demo2">response 2</p>
<script>
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myObj = JSON.parse(this.responseText);
document.getElementById("demo").innerHTML = myObj.response.docs[0].id;
//myObj.response.docs[0].id is the value/variable I need for the next httprequest
}
};
xhttp.open("GET", "https://geodata.nationaalgeoregister.nl/locatieserver/v3/suggest?q=" + document.getElementById("zip").value + "+" + document.getElementById("housenr").value + "&wt=json", true);
xhttp.send();
};
function loadDoc2() {
var url = "https://geodata.nationaalgeoregister.nl/locatieserver/v3/lookup?id=adr-16dc4e7caee6f2b34222fb02b91a464e" //the value/variable myObj.response.docs[0].id should be the last part of the url (from "adr." to "64e")
var vhttp = new XMLHttpRequest();
vhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var Obj = JSON.parse(this.responseText);
document.getElementById("demo2").innerHTML = this.responseText;
}
};
vhttp.open("GET", url, true);
vhttp.send();
};
</script>
</body>
</html>
you have to pass id to loadDoc2 as :
function loadDoc2(id) {
var url = "https://geodata.nationaalgeoregister.nl/locatieserver/v3/lookup?id="+id;//the value/variable myObj.response.docs[0].id should be the last part of the url (from "adr." to "64e")
var vhttp = new XMLHttpRequest();
vhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var Obj = JSON.parse(this.responseText);
document.getElementById("demo2").innerHTML = this.responseText;
}
};
vhttp.open("GET",url, true);
vhttp.send();
};
and call it on success of loadDoc:
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myObj = JSON.parse(this.responseText);
document.getElementById("demo").innerHTML = myObj.response.docs[0].id;
loadDoc2(myObj.response.docs[0].id)
//myObj.response.docs[0].id is the value/variable I need for the next httprequest
}
};
xhttp.open("GET", "https://geodata.nationaalgeoregister.nl/locatieserver/v3/suggest?q=" + document.getElementById("zip").value +"+"+ document.getElementById("housenr").value +"&wt=json", true);
xhttp.send();
};
You can simply call loadDoc2() with a parameter for the id:
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myObj = JSON.parse(this.responseText);
var response_id = myObj.response.docs[0].id;
document.getElementById("demo").innerHTML = response_id;
//myObj.response.docs[0].id is the value/variable I need for the next httprequest
loadDoc2(response_id);
}
};
xhttp.open("GET", "https://geodata.nationaalgeoregister.nl/locatieserver/v3/suggest?q=" + document.getElementById("zip").value +"+"+ document.getElementById("housenr").value +"&wt=json", true);
xhttp.send();
};
function loadDoc2(response_id = '') {
var url = "https://geodata.nationaalgeoregister.nl/locatieserver/v3/lookup?id="+response_id;
var vhttp = new XMLHttpRequest();
vhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var Obj = JSON.parse(this.responseText);
document.getElementById("demo2").innerHTML = this.responseText;
}
};
vhttp.open("GET",url, true);
vhttp.send();
};
In the onreadystatechange handler, you can then extract the id into request_id and call loadDoc2(request_id) with it.Also, don't forget to change the onclick-handler to only call loadDoc():
<button type="button" onclick="loadDoc();" >Get Content</button>
I know the URL is working as intended as i logged that to the console and it is fine. However I can't get "Good News" to log to the console when readyState == 4 and status == 200. I tried removing readState and it still wouldn't log. I tried logging the status and It would only fire once with a value of 0. This is the first time I am working with Ajax so any help is appreciated.
function setupRequest(){
var bttn = document.querySelector('#send');
bttn.addEventListener('click', sendData)
}
setupRequest();
function sendData () {
console.log('ran')
var url = 'localhost/bev/drinks.php';
var data = document.getElementById('input').value;
url += '?' + 'alcohol=' + data;
console.log(url)
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
console.log('good news')
console.log(this.responseText)
} else {
console.log(this.status)
}
}
request.open('GET', url, true);
request.send;
console.log('sent')
}
You need to actually call send(). You aren't doing anything whenever you say request.send;
function setupRequest() {
var bttn = document.querySelector('#send');
bttn.addEventListener('click', sendData)
}
setupRequest();
function sendData() {
console.log('ran')
var url = 'https://jsonplaceholder.typicode.com/posts';
var data = document.getElementById('input').value;
//url += '?' + 'alcohol=' + data;
console.log(url)
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log('good news')
console.log(this.responseText)
} else {
console.log(this.status)
}
}
request.open('GET', url, true);
// You wrote (without parentheses):
///////////////////
// request.send; //
///////////////////
// You need to write
request.send();
console.log('sent')
}
<button type="button" id="send">Btn</button>
<input type="text" id="input">
I have some problems with returning a value from a function into a variable. It is apparently "undefined". This apparently happens due to the asynchronity of JavaScript. But in my case I don't know how to circumvent it with "callbacks" or "promises". Please see code below. I would like to return the exchange rate saved in "value" back to "rate" and use it further in my code. Any ideas?
var rate = rateCalc();
var currency = "EUR";
function rateCalc(){
var value;
if (currency != "EUR") {
var xmlhttp = new XMLHttpRequest();
var rateURL = "http://query.yahooapis.com/v1/public/yql?q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes%3Fs%3D"+"EUR"+"HKD"+"%253DX%26f%3Dl1n'%20and%20columns%3D'rate%2Cname'&format=json";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var json = JSON.parse(xmlhttp.responseText);
value = json.query.results.row.rate;
alert("At this position the value is defined: "+ value);
return value;
}
}
xmlhttp.open("GET", rateURL, true);
xmlhttp.send();
}
else {
value = 1;
return value;
}
}
alert("The return statement somehow didn't work: "+ rate);
I'm a newbie, by the way. So sorry, if this question has already been asked like a million times before.
Thanks
René
You can't return anything from a async function in JS. So create a new function and use it as a callback function. See the below example.
var rate = rateCalc();
var currency = "EUR";
function rateCalc(){
var value;
if (currency != "EUR") {
var xmlhttp = new XMLHttpRequest();
var rateURL = "http://query.yahooapis.com/v1/public/yql?q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes%3Fs%3D"+"EUR"+"HKD"+"%253DX%26f%3Dl1n'%20and%20columns%3D'rate%2Cname'&format=json";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var json = JSON.parse(xmlhttp.responseText);
value = json.query.results.row.rate;
alert("At this position the value is defined: "+ value);
valueCallBack(value); //Callback function
}
}
xmlhttp.open("GET", rateURL, true);
xmlhttp.send();
}
else {
value = 1;
return value;
}
}
function valueCallBack(value){
console.log("value is " + value);
}
Update : You can use the Promise API introduced in the ES6 or use JQUERY deferred objects.
xmlhttp.send() shouldn't be empty. Try this. I hope it will do the job!
xmlhttp.send(null);
You can send the response value to another function so when you have a value it will be displayed without it being undefined.
Try this:
rateCalc();
var currency = "EUR";
function rateCalc() {
var value;
if (currency != "EUR") {
var xmlhttp = new XMLHttpRequest();
var rateURL = "http://query.yahooapis.com/v1/public/yql?q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes%3Fs%3D"+"EUR"+"HKD"+"%253DX%26f%3Dl1n'%20and%20columns%3D'rate%2Cname'&format=json";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var json = JSON.parse(xmlhttp.responseText);
value = json.query.results.row.rate;
show(value);
}
};
xmlhttp.open("GET", rateURL, true);
xmlhttp.send();
} else {
value = 1;
show(value);
}
}
function show(rate) {
alert("Value: "+ rate);
}
So this is how I changed the code now. The call back function is used for all further calculations with the called back value. Thanks again to #Jijo John and #nx0side.
var currency = "HKD";
var value;
if (currency != "EUR")
{
var xmlhttp = new XMLHttpRequest();
var rateURL = "http://query.yahooapis.com/v1/public/yql?q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes%3Fs%3D"+"EUR"+"HKD"+"%253DX%26f%3Dl1n'%20and%20columns%3D'rate%2Cname'&format=json";
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
var json = JSON.parse(xmlhttp.responseText);
value = json.query.results.row.rate;
valueCallBack(value); //Callback function
}
}
xmlhttp.open("GET", rateURL, true);
xmlhttp.send();
}
else
{
valueCallBack(1);
}
//in this function all further calculations with "value" need to take place.
function valueCallBack(value)
{
//example
var result = 70000/value;
console.log("Result is " + result);
}
Please help i have been trying from 1 hours and not able to get whats wrong
<!DOCTYPE html>
<html>
<body>
<div id="id01">Result<br/></div>
<script>
var xmlhttp = new XMLHttpRequest();
var url = "http://it-ebooks-api.info/v1/book/2279690981";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myArr = JSON.parse(xmlhttp.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 = arr[i].ID + arr[i].Title + arr[i].Description;
}
document.getElementById("id01").innerHTML = out;
}
</script>
</body>
</html>
I am trying to fetch details from http://it-ebooks-api.info/v1/book/2279690981 but it show only empty array being returned. What changes are required ?
Modification
I added [ ] on JSON object and it worked .. Please can someone explain me.
Thank in advance :)
The response does not contain an array, so the for loop is not needed and this should get you the result you are looking for:
<!DOCTYPE html>
<html>
<body>
<div id="id01">Result<br/></div>
<script>
var xmlhttp = new XMLHttpRequest();
var url = "http://it-ebooks-api.info/v1/book/2279690981";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myresponse = JSON.parse(xmlhttp.responseText);
myFunction(myresponse);
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
function myFunction(response) {
var out = "";
var i;
out = "<p>" + response.ID + response.Title + response.Description + "<p>";
document.getElementById("id01").innerHTML = out;
}
</script>
</body>
If you use the full listing available from http://it-ebooks-api.info/v1/search/php, then you need the for loop to go through the array like this:
<!DOCTYPE html>
<html>
<body>
<div id="id01">Result<br/></div>
<script>
var xmlhttp = new XMLHttpRequest();
var url = "http://it-ebooks-api.info/v1/search/php";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myresponse = JSON.parse(xmlhttp.responseText);
myFunction(myresponse.Books);
}
}
function myFunction(Books) {
var out = "";
for (var i = 0; i < Books.length; i++) {
out += "<p>ID: " + Books[i].ID + "</p>" + "<p>Title: " + Books[i].Title + "</p>" + "<p>Description: " + Books[i].Description + "</p>"
}
document.getElementById("id01").innerHTML = out;
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
</script>
</body>
</html>
And to make it slightly more elegant, you could have a function that adds the book and if you get only one book you can call it directly from the onreadystatechange, and if you have the full listing, then you can loop it through, but still use the same function. So something like this:
<!DOCTYPE html>
<html>
<body>
<div id="id01">Result<br/></div>
<script>
var xmlhttp = new XMLHttpRequest();
var url = "http://it-ebooks-api.info/v1/search/php";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var response = JSON.parse(xmlhttpo.responseText);
if (response.Books) { // If the response object has Books array, we pass it to the parseBooks functoin to add them all one by one.
parseBooks(response.Books)
} else {
addBook(response); // If there is no Books array, we assume that there is only one book and add it to the list with addBook function.
}
}
}
function addBook (Book) {
var text = document.getElementById("id01").innerHTML;
var body = "<p>ID: " + Book.ID + "</p><p>Title: " + Book.Title + "</p><p>Description: " + Book.Description + "</p>";
document.getElementById("id01").innerHTML = text + body; // Append the innerHTML with the new Book.
}
function parseBooks(Books) {
for (var i = 0; i < Books.length; i++) {
addBook(Books[i]) // Add all books in the array one by one
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
</script>
</body>
</html>
You JSON feed is just a simple object and not an Array of objects. Note the opening curly braces in the returned feed: {}
You should then change your myFunction function so it goes through an object and not an array just by removing the for loop:
function myFunction(obj) {
var out = "",
id01 = document.getElementById("id01");
out = obj.ID + obj.Title + obj.Description;
id01.innerHTML = id01.innerHTML + out;
}
Edit:
You can use the same function then inside a for loop when you have to parse an Array of Objects.
Taking as a feed the JSON returned from http://it-ebooks-api.info/v1/search/php, you can retrieve the Books value and then loop through it:
var xmlhttp = new XMLHttpRequest();
var url = "http://it-ebooks-api.info/v1/book/2279690981";
var url2 = "http://it-ebooks-api.info/v1/search/php";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var rslt = JSON.parse(xmlhttp.responseText);
console.log(rslt);
var books = rslt.Books;
for (var i = 0; i < books.length; i++)
{
myFunction(books[i]);
}
}
}
xmlhttp.open("GET", url2, true);
xmlhttp.send();
The function below gets results in ie but not on the other browsers. Any suggestion?
function show_packet(str, company) {
var cam = document.getElementById("company");
if (window.XMLHttpRequest) {
var xmlhttp = new XMLHttpRequest();
} else {
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("packet_1").innerHTML = xmlhttp.responseText;
document.getElementById("icon_1").innerHTML = "";
}
}
xmlhttp.open("GET", "show_packet.php?car_moto=" + encodeURIComponent(str, true) + "&cam=" + encodeURIComponent(cam.value, true));
xmlhttp.send();
}
vars and functions are hoisted to the top of their containing function. Declare your var once at the top, and only assign it in the if/else.