AJAX and datalists - javascript

I'm trying to use XML to get a list of cities from a website, then go through and add each of the cities to a datalist so that when I put in an input it will filter the cities in the list.
example of city list:
Aleppo
Alexandria
Alger
Almaty
Ankara
Anshan
Baghdad
Baku
Bandung
Bangalore
Bangkok
Barcelona
*[Each city name is on a new line]
current html:
<div id="namearea">
<h2>City Name:</h2>
<div>
<input id="citiesinput" list="cities">
<datalist id="cities"></datalist>
<button id="search">
Search
</button>
<span class="loading" id="loadingnames">
Loading...
</span>
</div>
</div>
current JS code:
window.onload = function() {
var request = new XMLHttpRequest();
request.onload = processCities;
request.open("GET", "url", true);
request.send();
};
Inspecting the page with Firebug shows that nothing is being added to the datalist, so I'm wondering what I'm doing wrong. I also tried using .responseText rather than .responeXML but it didn't make any difference.
[Fixed]
I changed the processCities() function to:
function processCities() {
var response = this.responseText;
var city = response.split("\n");
var options = "";
for(var i = 0; i < response.length; i++) {
options += "<option value='"+city[i]+"'>\n";
}
document.getElementById("cities").innerHTML = options;
}
This code seems to work.

Here is an example of making the request. If you really are getting XML, you'll have to parse it. It's better if you could get json.
var request = new XMLHttpRequest();
request.open('GET', '/my/url', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
var data = JSON.parse(request.responseText);
} else {
// We reached our target server, but it returned an error
}
};
request.onerror = function() {
// There was a connection error of some sort
};
request.send();

Related

Data not displaying in JavaScript API

I am making a Pokedex API as a side project and I can not display the data needed to display in the different text boxes. I am using a GET request to request the height, weight, type, and ability.
<script>
$("button").click( function(){
var pokemonName = $('pokemon').val(pokemon);
event.preventDefault();
getPokemonData(pokemonName);
})
function getPokemonData(pokemonName){
var request = new XMLHttpRequest()
//GET request with link
request.open('GET','https://pokeapi.co/api/v2/pokemon/' + pokemonName, true);
// request for data
request.onload =function(){
var data = JSON.parse(this.response)
if(request.status >= 200 && request.status <= 400)
{
// outputs data
$(pokemonheight).val(response.height)
$(pokemonweight).val(response.weight)
$(pokemonAblity).val(response.ability)
$(pokemonType).val(response.type)
}
else
{
alert ("Error");
}
request.send();
}
}
</script>
</html>
I have tried setting a variable that would be equal to the response JSON element and then input that into the value of the textbox.
I do not have anything returned as expected or input displayed in the console if declared.
Issue(s)
There were a few issues with your code:
var pokemonName = $('pokemon').val(pokemon); you are setting the value of some element named pokemon (not valid) here
var data = JSON.parse(this.response); where is this.response being set? Shouldn't we be receiving response in the callback?
request.send(); is inside of the onload event, so the request never gets sent
Critiques
My main critique here is that you included a fairly large library (jQuery), and didn't utilize it to make the request. $.ajax is well documented and cleans up a lot of the intricacies of XMLHttpRequest.
The solution
$("button").click(function() {
var pokemonName = $('#pokemon').val();
//event.preventDefault();
getPokemonData(pokemonName);
})
function getPokemonData(pokemonName) {
var request = new XMLHttpRequest()
//GET request with link
request.open('GET', 'https://pokeapi.co/api/v2/pokemon/' + pokemonName, true);
// request for data
request.onload = function(response) {
var data = JSON.parse(response.currentTarget.response)
if (request.status >= 200 && request.status <= 400) {
// outputs data
console.log(data)
} else {
alert("Error");
}
}
request.send();
}
<input id="pokemon" value="12" />
<button>search</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Taking all the above issues into account, I was able to get a working example of what it should ultimately look like.
Hope this helps!

JQuery display next item from array

I am trying to display next item from array json with displayItem function, but after click on the button, the form reloads the first value (arrayResponse[0]). What should I do to display the next item instead?
$(document).ready(function () {
var firstElement;
var arrayResponse;
var index = 0;
var request = new XMLHttpRequest();
// When the file has loaded,
request.onload = function () {
// parse the JSON text into an array of post objects.
arrayResponse = JSON.parse(request.responseText);
var firstelement = arrayResponse[0];
$("#name").val(firstelement.name);
$("#author").val(firstelement.author);
$("#content").val(firstelement.content);
// Pass the posts array to the callback.
};
request.open("GET", "http://127.0.0.1:8887/posts.json", true);
request.send(null);
$("#nextButton").bind("click", function () {
displayItem(arrayResponse[++index])
});
function displayItem(item) {
$("#name").val(item.name);
$("#author").val(item.author);
$("#content").val(item.content);
}
});
I checked your code with this test json
I created this jsfiddle and it seems to work perfect. There must be some kind of error with your json.
Html:
<input id="name" /><br>
<input id="author" /><br>
<input id="content" /><br>
<button id="nextButton">Next</button>
Js:
$(document).ready(function() {
var firstElement;
var arrayResponse;
var index =0;
var request = new XMLHttpRequest();
// When the file has loaded,
request.onload = function () {
// parse the JSON text into an array of post objects.
arrayResponse = JSON.parse(request.responseText);
firstelement = arrayResponse[0];
$("#name").val(firstelement.id);
$("#author").val(firstelement.name);
$("#content").val(firstelement.username);
// Pass the posts array to the callback.
};
request.open("GET", "https://jsonplaceholder.typicode.com/users", true);
request.send(null);
$("#nextButton").bind("click", function(){
displayItem(arrayResponse[++index])
});
function displayItem(item) {
$("#name").val(item.id);
$("#author").val(item.name);
$("#content").val(item.username);
}
});
Change this :
$("#nextButton").bind("click", function(){
displayItem(arrayResponse[++index])
});
to this:
$("#nextButton").bind("click", function(){
displayItem(arrayResponse[index]);
index++;
});

Using AJAX to create a datalist

I'm trying to add to a datalist using AJAX. The webpage I'm requesting just has names of cities each on their own line. I basically have:
(function() {
"use strict";
window.onload = function() {
fetch("cities");
};
function fetch(mode) {
var request = new XMLHttpRequest();
request.onload = getCities();
request.open("GET", "https://weather.com/weather/mode=" + mode, true);
request.send();
}
function getCities() {
//loop while there's data/string to grab {
var city = document.createElement("option");
city.innerHTML = this.responseText; //set the option as the name of the city from the request
document.getElementById("cities").appendChild(city);
}
}
}) ();
The webpage is just a filler for a webpage that I'm using on a server but I'm trying to create a new option tag for each string and append it to a datalist in my html but I'm having an issue catching anything. For some reason I'm just getting an undefined error. Sorry I'm kind of new to javascript and AJAX.
webpage layout of the page of requesting:
Abidjan
Accra
Adana
Addis Abeba
Ahmedabad
Aleppo
Alexandria
Alger
Almaty
Ankara
Anshan
Baghdad
Baku
Bandung
Bangalore
Bangkok
You're missing brackets () off your function calls
(function() {
"use strict";
window.onload = function() {
fetch("cities");
};
function fetch(mode) {
var request = new XMLHttpRequest();
request.onload = getCities(); // <- brackets missing here
request.open("GET", "https://weather.com/weather/mode=" + mode, true);
request.send(); // <- and here
}
function getCities() {
var city = document.createElement("option");
document.getElementById("cities").innerHTML = this.responseText;
}
}) ();
It's also very unclear to me how your getCities function is supposed to work. You're creating an option set, but not adding it to your DOM. I'm also not sure what this.responseText is supposed to be.

Vanilla javascript: Get a specific element of page in an ajax get request

I'm trying to get #test1 from another page and append it to #test3 of the main page. This is what I have done so far:
<div id="test3"></div>
var request = new XMLHttpRequest();
request.open('GET', '//jsbin.com/wemowe', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
var resp = request.responseText;
var parser = new DOMParser();
var xmlDoc = parser.parseFromString(resp,"text/xml");
var tds = xmlDoc.getElementById("test1");
console.log(xmlDoc);
document.getElementById('test3').innerHTML=tds.innerHTML;
} else {}
};
request.onerror = function() {};
request.send();
Here is JSBin
Any suggestion to make it work?
The doc type is causing the issue here.
var xmlDoc=parser.parseFromString(resp, "text/xml");
change it to:
var xmlDoc=parser.parseFromString(resp, "text/html");

Multiple XMLHttpRequests not working

I am puzzled about this. I have two XMLHttpRequests that operate on Select elements of my HTML file (each one operates on a different Select element right when the HTML file is loaded). I am using a callback function as was recommended on W3CSchools. If my variable xmlHttp is defined outside of my callback function, only the second request works, and the first one gets deleted before it has a chance to finish. If I put 'var' in front of it the same thing happens. However, if my variable is inside the function with 'var' in front of it, then absolutely nothing happens. I have narrowed it down to where to the line that says "HERE!!!!!" is where the program seems to hang. I know the loadXMLDoc function does not actually finish because when I put an alert outside of it, nothing happens. I am supposing it has something to do with the 'if' part and the program not being able to recognize xmlHTTP, even though it was locally defined. I am still pretty new to JavaScript and just want to be able to run multiple XMLHttpRequest objects at once without them getting in each other's way but also without the page hanging. Any ideas why this does not work?
HTML:
<form>
<select id="stateSelectCities">
<!-- Will be populated with MySQL -->
</select>
<select id="citySelect">
<option>Select a State</option>
</select>
<br />
<br />
<select id="stateSelectCounties">
<!-- Will be populated with MySQL -->
</select>
<select id="countySelect">
<option>Select a State</option>
</select>
<p id="xmltest"></p>
<p id="currentState"></p>
<p id="sc"></p>
<p id="rs"></p>
<p id="st"></p>
</form>
JavaScript:
<script type="text/javascript">
function loadXMLDoc(method, data, url, cfunc) {
var xmlHTTP = new XMLHttpRequest();
xmlHTTP.onreadystatechange = cfunc;
xmlHTTP.open(method, url, true);
if (data) {
xmlHTTP.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlHTTP.send(data);
} else {
xmlHTTP.send();
}
}
function returnStateListForCounties() {
loadXMLDoc('GET', null, "stateslist.xml", function() {
document.getElementById('countySelect').disabled = true;
if (xmlHTTP.readyState == 4 && xmlHTTP.status == 200) {
// Read the XML Data and Populate Counties States Menu
var response = xmlHTTP.responseXML;
var states = response.getElementsByTagName('state');
for (i = 0; i < states.length; i++) {
var option = document.createElement('option');
option.innerHTML = states[i].childNodes[0].nodeValue;
option.setAttribute('onmouseup', 'returnCounties(this.innerHTML)');
document.getElementById("stateSelectCounties").add(option);
}
}
//document.getElementById("sc").innerHTML = 'statusCode: ' + xmlHTTP.status;
//document.getElementById("rs").innerHTML = 'readyState: ' + xmlHTTP.readyState;
//document.getElementById("st").innerHTML = 'statusText: ' + xmlHTTP.statusText;
})
}
function returnStateListForCities() {
loadXMLDoc('GET', null, 'stateslist.xml', function() {
document.getElementById('citySelect').disabled = true;
// HERE!!!!!
if (xmlHTTP.readyState == 4 && xmlHTTP.status == 200) {
// Read the XML Data and Populate Cities States Menu
var response = xmlHTTP.responseXML;
var states = response.getElementsByTagName('state');
for (i = 0; i < states.length; i++) {
var option = document.createElement('option');
option.innerHTML = states[i].childNodes[0].nodeValue;
option.setAttribute('onmouseup', 'returnCities(this.innerHTML)');
document.getElementById("stateSelectCities").add(option);
}
}
document.getElementById("sc").innerHTML = 'statusCode: ' + xmlHTTP.status;
document.getElementById("rs").innerHTML = 'readyState: ' + xmlHTTP.readyState;
document.getElementById("st").innerHTML = 'statusText: ' + xmlHTTP.statusText;
})
}
//returnStateListForCounties();
returnStateListForCities();
</script>
The problem here is xmlHTTP variable which is defined inside loadXMLDoc function and try to use again inside returnStateListForCounties function, I'll do it like this:
function loadXMLDoc(method, data, url, cfunc) {
var xmlHTTP = new XMLHttpRequest();
xmlHTTP.onreadystatechange = function() {
if (xmlHTTP.readyState == 4 && xmlHTTP.status == 200)
{
cfunc(xmlHTTP.responseXML); //Call passed func with the resulting XML
}
};
xmlHTTP.open(method, url, true);
if (data) {
xmlHTTP.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlHTTP.send(data);
} else {
xmlHTTP.send();
}
}
This way you encapsulate the data recovery.

Categories