I'm learning and trying to write a simple stock quote tool using Python-Flask and Javascript.
I specifically want to learn plain Javascript. My code is working, but what I don't understand is when I'm watching the developer console, I get 3 error messages printed before I get the successful console.log(response).
Is it simply that the code loops 3 times before the response comes back, so it logged 'ERROR' each of those times before finally returning the 200 status? Would someone explain it to me or point me to a good article/post?
My event listener:
document.getElementById("btn_quote").addEventListener("click", getQuote);
The ajax call:
function getQuote(e){
e.preventDefault();
var ticker = document.getElementById("ticker").value
var shares = document.getElementById("shares").value
var url = "/quote/"+ticker+"/"+shares
// Fetch the latest data.
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState === XMLHttpRequest.DONE) {
if (request.status === 200) {
var response = JSON.parse(request.response);
console.log(response);
}
} else {
// TODO, handle error when no data is available.
console.log('ERROR');
return false;
}
};
request.open('GET', url);
request.send();
}
It's not returning separate HTTP status codes, its returning different ready states.
Change your console.log("ERROR");. To console.log(request.readyState);.
Then you will see what it is reporting and why.
i think you should be checking your readyState values with the actual values of the response. For you reference, following are the possible values of readyState:
0: request not initialized
1: server connection established
2: request received
3: processing request
4: request finished and response is ready
So you could basically check it to be 4 in your case:
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState === 4) {
//response statements
} else {
//error statements
}
};
Basically, ajax calls will get notified for the following events which is called as readyStateChange event.
For most cases, you used to get 4 ready state changes based on the speed of the connection (rare cases only only one if it's very quick) and you should check whether it is 4 which means the response is completed now.
To check whether the request is suceess or not, you should check the request.status === 200 which means success and can check for other http status code for errors like 404, 500 etc.
document.getElementById("btn_quote").addEventListener("click", getQuote);
document.getElementById("btn_quote_error").addEventListener("click", getQuoteError);
function getQuote(e){
e.preventDefault();
var ticker = document.getElementById("ticker").value;
var shares = document.getElementById("shares").value;
//var url = "/quote/" + ticker + "/" + shares;
var url = 'http://stackoverflow.com/';
// Fetch the latest data.
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
console.log(request.readyState);
if (request.readyState === XMLHttpRequest.DONE) {
console.log(request.status);
if (request.status === 200) {
//var response = JSON.parse(request.response);
//console.log(response);
}
}
//else {
// TODO, handle error when no data is available.
//console.log('ERROR');
//return false;
//}
};
request.open('GET', url, true);
request.send();
}
function getQuoteError(e){
e.preventDefault();
var ticker = document.getElementById("ticker").value;
var shares = document.getElementById("shares").value;
//var url = "/quote/" + ticker + "/" + shares;
var url = 'http://stackoverflow404.com/';
// Fetch the latest data.
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
console.log(request.readyState);
if (request.readyState === XMLHttpRequest.DONE) {
console.log(request.status);
if (request.status === 200) {
//var response = JSON.parse(request.response);
//console.log(response);
}
}
//else {
// TODO, handle error when no data is available.
//console.log('ERROR');
//return false;
//}
};
request.open('GET', url, true);
request.send();
}
<input type="text" id="ticker"/>
<input type="text" id="shares"/>
<input type="button" id="btn_quote" value="Get Quote" />
<input type="button" id="btn_quote_error" value="Get Quote Error" />
Related
I have a problem with uploading a file to a node server via HTML. In the page I have this input:
<input type="file" id = "csvFile" />
<input type="submit" name="submit" onclick="send_data()" />
Then I have the send_data function that looks like this:
function send_data(){
let file = document.getElementById("csvFile");
const xhr = new XMLHttpRequest();
xhr.open("GET", file, true);
xhr.setRequestHeader("Content-type", "text/csv");
xhr.onreadystatechange = () =>{
if(xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200){
console.log("done");
}
xhr.send();
}
Here there is the first problem, because the arrow function of the ready state never executes.
In any case, it's the first time I do something like this, so I don't know how I can make sure that my server gets the file and processes it. Can someone help me?
This should do the trick:
let file = document.getElementById("csvFile").files[0];
let xhr = new XMLHttpRequest();
let formData = new FormData();
formData.append("csvFile", file);
xhr.open("POST", '${your_full_address}');
xhr.onreadystatechange = function () {
// In local files, status is 0 upon success in Mozilla Firefox
if (xhr.readyState === XMLHttpRequest.DONE) {
var status = xhr.status;
if (status === 0 || (status >= 200 && status < 400)) {
// The request has been completed successfully
console.log(xhr.responseText);
} else {
// Oh no! There has been an error with the request!
}
}
};
xhr.send(formData);
Refer: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/onreadystatechange
I am building an web that allows user to like a post when they click a button. CreateLike function calls API and creates a like object however, I would like to have the number of likes updated right away without reloading. I built another API that returns the number of likes for a post. Function LikeCount should put the number of likes into the p tag. It works initially when I load the page however, the value does not change when I click the button even though I can see that the API is called. (After reloading the page the number changes as expected) What am I doing wrong?
I have this HTML:
<p class="like-count" id={{post.id}}></p>
<script>LikeCount({{post.id}});</script>
<button type="button" class="btn-like" onclick="CreateLike({{user.id}},{{post.id}})"></button>
with JS functions:
function CreateLike (userid,postid) {
xhr = new XMLHttpRequest();
var url = "{% url 'likes' %}";
var csrftoken = getCookie('csrftoken')
xhr.open("POST", url, true);
xhr.setRequestHeader("X-CSRFToken",'{{ csrf_token }}')
xhr.setRequestHeader("Content-type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var json = JSON.parse(xhr.responseText);
console.log(json.email + ", " + json.name)
}
}
var data = JSON.stringify({csrfmiddlewaretoken:csrftoken,"user":userid,"post":postid});
xhr.send(data);
LikeCount(postid);
}
function LikeCount(postid) {
var xmlhttp = new XMLHttpRequest();
var url = "{% url 'likecount' id=112233 %}".replace("112233", postid);
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 = arr.like_count;
document.getElementById(postid).innerHTML = out;
}
}
Like count API looks like this:
{
"like_count": 1
}
if(xhr.readyState === XMLHttpRequest.DONE) {
var status = xhr.status;
if (status === 0 || (status >= 200 && status < 400)) {
LikeCount(); //Put your get like count here
} else {
// Handle Errors
}
}
Call LikeCount only after receiving the response of your POST request. Right now you're immediately sending a GET request without ensuring if the previous POST request got completed.
Added
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 201) {
var myArr = JSON.parse(this.responseText);
LikeCount(myArr.post);
}
};
before
xhr.send(data);
and it fixed the issue.
I'm attempting to create a dashboard that logs into an API then refreshes certain data elements that is fully automated. I can login and authenticate but after googling unsure how to 'chain' the GET request after the 'POST'
I've tried watching a few youtube tutorials and creating functions, attaching them to buttons and divs but I just can't get the data to display. The first batch of code completes and logs in OK, but then sits there and times out. I tried just adding a second open and making the login synchronous but it failed
<script type="text/javascript">
const xhr = new XMLHttpRequest();
var data = 'username=user&password=password';
xhr.onreadystatechange = function()
{
if (xhr.readyState == "4")
{
if (xhr.status == "200")
{
console.log(xhr.responseText);
}
if (xhr.status = "404")
{
console.log("FnF");
}
}
}
xhr.open('post','https://apiServer:8443/api/login', true)
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
xhr.setRequestHeader("Accept", "application/xml")
//xhr.open('get', 'https://apiServer:8443/api/resource/items', true);
xhr.send();
I'm expecting the login to be done behind the scenes and not visible, and just have the GET request show data in a div (I'll try and tidy up the xml response when I get the data working first).
In your code you never use your data variable :
const xhr = new XMLHttpRequest();
var data = 'username=user&password=password';
xhr.onreadystatechange = function()
{
if (xhr.readyState == "4")
{
if (xhr.status == "200")
{
console.log(xhr.responseText);
}
if (xhr.status = "404")
{
console.log("FnF");
}
}
}
xhr.open('post','https://apiServer:8443/api/login', true)
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
xhr.setRequestHeader("Accept", "application/xml")
//xhr.open('get', 'https://apiServer:8443/api/resource/items', true);
xhr.send(data); // <====== HERE
hi guys I have this function:
its checking if the image URL is an actual image, but I want to change it , instead of console log I want it to return true or false,
function checkImage(url) {
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.send();
request.onload = function() {
status = request.status;
if (request.status == 200) //if(statusText == OK)
{
console.log("image exists");
} else {
console.log("image doesn't exist");
}
}
}
checkImage("https://picsum.photos/200/300");
I want checkImage to return True/False instead of console logging, but when i write return true or false, that doesn't seem to work,
anyone knows why?
If the whole purpose of this function is to check if the image exists with the intent of displaying a default image I would use a much simpler approach. Why not use the following method:
<img src="imagenotfound.gif" alt="Image not found" onerror="this.src='imagefound.gif';" />
This is described at further length here
Just change the console to callback may help u solve it
function checkImg(url,success,error){
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.send();
request.onload = function() {
status = request.status;
if (request.status == 200) //.if(statusText == OK)
{
success && success()
} else {
error && error()
}
}
}
Replace the Ajax with Image.onload()
How to send an http request with either post/get method using javascript as an eventhandler? Thanks! Paul
Okay, you don't want to use Ajax.
You can use an event handler to submit a form!
<a href='#' onclick='cow_submit("zoodle")'>send</a>
<form method='post' id='formie' action='find_some_action.php'>
<input type='hidden' id='snoutvar' name='snoutvar' value='snout'>
</form>
<script>
function cow_submit(a_var_to_set){
var plip=document.getElementById('formie');
var snout=document.getElementById('snoutvar');
snout.value=a_var_to_set;
plip.submit();
}
See https://developer.mozilla.org/en/DOM/form
use XmlHttpRequest
sample code:
var client = new XMLHttpRequest();
client.onreadystatechange = handler;
client.open("GET", "test.xml");
client.send();
function handler()
{
// your handler
}
You can use XMLHttpRequest for sending request from javascript
Sending GET request
var url = "get_data.php";
var params = "lorem=ipsum&name=binny";
http.open("GET", url+"?"+params, true);
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(null);
Sending POST request
var url = "get_data.php";
var params = "lorem=ipsum&name=binny";
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
And don't forget to encode parameters using encodeURIComponent for param value encoding in case of user input
e.g.
params="paramName="+encodeURIComponent(paramValue);
The standard class for doing this is XmlHttpRequest, but it's not universally supported. On some browsers you have to use ActiveXObject("Microsoft.XMLHTTP") instead.
Look into the jQuery system which provides HTTP download (AJAX style) methods regardless of the underlying browser APIs (hence avoiding a lot of the code shown in Tzury's answer).
The jQuery AJAX documentation is at http://docs.jquery.com/Ajax
You should try to add atring in a hidden field and then call the form.submit() to submit your form into the page define in action.
<script type="text/javascript">
function doTestFormSubmit(yourString) {
document.getElementById("myString").value=myString;
document.getElementById("testForm").submit();
}
</script>
<form name="testForm" id="testForm" action="yourDesiredPage.php" method="post">
<input type="hidden" name="myString" id="myString" value=""/>
</form>
Ajax Tutorial (http://code.google.com/edu/ajax/tutorials/ajax-tutorial.html)
var obj;
function ProcessXML(url) {
// native object
if (window.XMLHttpRequest) {
// obtain new object
obj = new XMLHttpRequest();
// set the callback function
obj.onreadystatechange = processChange;
// we will do a GET with the url; "true" for asynch
obj.open("GET", url, true);
// null for GET with native object
obj.send(null);
// IE/Windows ActiveX object
} else if (window.ActiveXObject) {
obj = new ActiveXObject("Microsoft.XMLHTTP");
if (obj) {
obj.onreadystatechange = processChange;
obj.open("GET", url, true);
// don't send null for ActiveX
obj.send();
}
} else {
alert("Your browser does not support AJAX");
}
}
function processChange() {
// 4 means the response has been returned and ready to be processed
if (obj.readyState == 4) {
// 200 means "OK"
if (obj.status == 200) {
// process whatever has been sent back here:
// anything else means a problem
} else {
alert("There was a problem in the returned data:\n");
}
}
}