Response is received without any problems, but properties which must be changed after response by received data are undefined. Probably they getting values from the temp variables way too fast. How to fix this?
By the way, is there an option to avoid those temp variables and use properties of the object inside if statement? It would be so much better. Tried different ways, but it didn't work =(
var tickerBittrex = function(tickerName)
{
this.tickerName = tickerName;
this.requestURL = "https://bittrex.com/api/v1.1/public/getticker?market=" + tickerName;
/* Properties */
this.success = false;
this.message = "";
this.Last = 0;
this.sendRequest = function()
{ /* temp variables */
var success;
var message;
var Last;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function(success, message, Last)
{
if (this.readyState == 4 && this.status == 200)
{
console.log(xhttp.responseText); // test
var response = JSON.parse(xhttp.responseText); // parsed response
console.log(response); // test
success = response.success;
message = response.message;
Last = response.result.Last;
console.log(Last); // test
console.log("xhttp.status: " + xhttp.status + " readyStat:" + xhttp.readyStat); // test
}
};
xhttp.open("GET", this.requestURL, true);
xhttp.send();
this.success = success;
this.message = message;
this.Last = Last;
}
}
var bittrexBTC = new tickerBittrex("usdt-btc");
bittrexBTC.sendRequest();
this should work:
var tickerBittrex = function(tickerName) {
this.tickerName = tickerName;
this.requestURL = "https://bittrex.com/api/v1.1/public/getticker?market=" + tickerName;
/* Properties */
this.success = false;
this.message = "";
this.Last = 0;
var self = this;
this.sendRequest = function() { /* temp variables */
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function(success, message, Last) {
var success;
var message;
var Last;
if (this.readyState == 4 && this.status == 200) {
console.log(xhttp.responseText); // test
var response = JSON.parse(xhttp.responseText); // parsed response
console.log(response); // test
success = response.success;
message = response.message;
Last = response.result.Last;
console.log(Last, success, message); // test
self.success = success;
self.message = message;
self.Last = Last;
console.log(self);
console.log("xhttp.status: " + xhttp.status + " readyState:" + xhttp.readyState); // test
}
};
xhttp.open("GET", this.requestURL, true);
xhttp.send();
}
}
var bittrexBTC = new tickerBittrex("usdt-btc");
bittrexBTC.sendRequest();
Explanation:
first,put code below in the onreadystatechange callback because before the callback executed the value of success,message,Last will be undefined.
this.success = success;
this.message = message;
this.Last = Last;
second:change this to self which defined in the tickerBittrex function,so can get the right this object.
var self = this;
so comes:
self.success = success;
self.message = message;
self.Last = Last;
Related
I am doing a XMLHttpRequest which is in it's own function. I want to return the price1 var to be used by other functions. But it seems to be lost in the scope. Code below -
var dataControl = (function () {
var getPrice = function(sym){
var xhttp = new XMLHttpRequest();
var response, price1;
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
response = JSON.parse(this.responseText);
price1 = response['Data'];
price1 = price1[0].open;
console.log(price1);
return price1;
}
};
xhttp.open("GET", "https://min-api.cryptocompare.com/data/histominute?fsym=XRP&tsym=USD&limit=60&aggregate=3&e=CCCAGG", true);
xhttp.send();
}
return {
getItem: function () {
getPrice();
}
}
})();
You can use the Callback Paradigm to get the data that you need
var dataControl = (function () {
var getPrice = function (cb) {
cb = (typeof cb === 'function' && cb) || function(){};
var xhttp = new XMLHttpRequest();
var response, price1;
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
response = JSON.parse(this.responseText);
price1 = response['Data'];
price1 = price1[0].open;
console.log(price1);
// Assuming error first callback paradign
cb(null, price1);
}
};
xhttp.open("GET", "https://min-api.cryptocompare.com/data/histominute?fsym=XRP&tsym=USD&limit=60&aggregate=3&e=CCCAGG", true);
xhttp.send();
}
return {
getItem: function (cb) {
getPrice(cb);
}
}
})();
dataControl.getItem(function(err, data){
if(err){
// Handle error
return;
}
console.log(data); // Value of price1
});
Why cannot I call variables that I have defined inside a function? This is my code...
var username;
var rank;
var steamid;
var avatar;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "null") {
} else {
var infoArr = JSON.parse(this.responseText);
var username = infoArr.username;
var rank = infoArr.rank;
var steamid = infoArr.steamid;
var avatar = infoArr.avatar;
testIt();
}
}
};
xhr.open("GET", "../getInfo.php", true);
xhr.send();
function testIt() {
alert(username);
}
Function testIt() is returning: undefined
What my code does is to get info from a JSON encoded page and make variables.
If you want to use the variables outside of the function, they need to be defined outside of the function.
var username, rank, steamid, avatar, infoArr, username, rank, steamid, avatar;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == "null") {
} else {
infoArr = JSON.parse(this.responseText);
username = infoArr.username;
rank = infoArr.rank;
steamid = infoArr.steamid;
avatar = infoArr.avatar;
testIt();
}
}
};
xhr.open("GET", "../getInfo.php", true);
xhr.send();
function testIt() {
alert(username);
}
I am using AJAX GET to get a local JSON file and it does that, but once i try to return it says undefined.
ScoreHandler = function () {
this.getScores = function() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var data = JSON.parse(this.responseText);
//This logs object
console.log(data);
return data;
}
};
xmlhttp.open("GET", "JSON/Scores.json", true);
xmlhttp.send();
};
};
HighScores = function (scoreHandler) {
var scoreHandler = scoreHandler;
var scores = this.scoreHandler.getScores();
//This logs undefined
console.log(scores);
}
Just implement a callback for response, something like this
ScoreHandler = function () {
this.getScores = function(callback) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var data = JSON.parse(this.responseText);
//This logs object
console.log(data);
if(typeof callback === 'function')
callback(data);
//return data;
}
};
xmlhttp.open("GET", "JSON/Scores.json", true);
xmlhttp.send();
};
};
HighScores = function (scoreHandler) {
var scoreHandler = scoreHandler; //why this line use it directly
var scores = this.scoreHandler.getScores(function(data){
console.log("response", data); //you can see the data here
});
//This logs undefined
console.log(scores);
}
I'm generating a series of variables in a loop (using JS), and I'm assigning them an .id and a .name based on the current index. At each loop I'm sending a request to the server using jQuery.post()method, but the returning response is just an empty variable.
Here's the code:
JavaScript
for ( var index = 0; index < 5; index++ ) {
var myVar = document.createElement('p');
myVar.id = 'myVarID' + index;
myVar.name = 'myVarName' + index;
//Send request to server
$(document).ready(function(){
var data = {};
var i = 'ind';
var id = myVar.id;
var name = myVar.name;
data[id] = name;
data[i] = index;
$.post("script.php", data, function(data){
console.log("Server response:", data);
});
});
}
PHP
<?php
$index = $_POST['ind'];
$myVar = $_POST['myVarID'.$index];
echo $myVar;
?>
Response: Server response: ''
If I instead set a static index in JS code, getting rid of the loop, so for example:
var index = 0;
I get the expected result: Server response: myVarName0
Why is this happening? And how can I solve it?
Assuming the php file is in order. I use this:
function doThing(url) {
getRequest(
url,
doMe,
null
);
}
function doMe(responseText) {
var container = document.getElementById('hahaha');
container.innerHTML = responseText;
}
function getRequest(url, success, error) {
var req = false;
try{
// most browsers
req = new XMLHttpRequest();
} catch (e){
// IE
try{
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
// try an older version
try{
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e){
return false;
}
}
}
if (!req) return false;
if (typeof success != 'function') success = function () {};
if (typeof error!= 'function') error = function () {};
req.onreadystatechange = function(){
if(req .readyState == 4){
return req.status === 200 ?
success(req.responseText) : error(req.status)
;
}
}
var thing = "script.php?" + url;
req.open("GET", thing, true);
req.send(null);
return req;
}
then use it like this:
doThing("myVarID="+myVar.id+"&i="+index);
also, you will have to change your PHP to something like this:
<?php
$index = $_GET['ind'];
$myVar = $_GET['myVarID'.$index];
echo $myVar;
?>
Obviously this code needs to be edited to suit your own needs
the function doMe is what to do when the webpage responds, in that example I changed the element with the id hahaha to the response text.
This won't win you any prizes but it'll get the job done.
Solution
It is working fine removing:
$(document).ready()
Working code
for ( var index = 0; index < 5; index++ ) {
var myVar = document.createElement('p');
myVar.id = 'myVarID' + index;
myVar.name = 'myVarName' + index;
//Send request to server
var data = {};
var i = 'ind';
var id = myVar.id;
var name = myVar.name;
data[id] = name;
data[i] = index;
$.post("script.php", data, function(data){
console.log("Server response:", data);
});
}
I have defined one root object that I want to use as "namespace" for the rest of my classes. Inside this root object i have two classes - TOOLS and PRESENTATION. In PRESENTATION class i need to call one of public methods from TOOLS. As I can tell after playing with console.log in every step of execution of this code problem is that return xhr.responseText don't pass anything back to tools.getData(configPath) and I'm ending up with undefined in console.log(pres.config).
CODE:
// Create Namespace
var AppSpace = AppSpace || {};
// Class and Constructor
AppSpace.Tools = function() {
//public methodts
this.test = function(arg) {
return arg
}
this.getData = function(path) {
var xhr = new XMLHttpRequest();
xhr.open('GET', path, false);
xhr.onreadystatechange = function() {
if (xhr.readyState !== 4) return;
if (xhr.status !== 0 && xhr.status !== 200) {
if (xhr.status === 400) {
console.log("Could not locate " + path);
} else {
console.error("app.getData " + path + " HTTP error: " + xhr.status);
}
return;
}
return xhr.responseText;
};
xhr.send();
}
}
// Class and Constructor
AppSpace.Presentation = function(initName, initfPath){
//private properties
var configPath = initfPath || 'config.json';
var configData = null;
var name = initName || 'Unnamed Presentation';
//private methods
var getConfigContent = function() {
return tools.getData(configPath);
}
var getConfigData = function() {
return JSON.parse(getConfigContent);
}
//public methodts
//public properties
this.name = null;
this.config = null;
this.debug = null;
//logic
this.name = name;
this.config = getConfigContent();
}
//execution
var tools = new AppSpace.Tools();
var pres = new AppSpace.Presentation('Some Name');
pres.debug = tools.test('value passed')
console.log(pres.debug);
console.log(pres.config);
console.log(pres.name);
Output in browsers console is:
value passed js-oop.dev:99
**undefined js-oop.dev:100**
Some Name js-oop.dev:101
Can anyone give little advice on this? TIA.
I mean that if you want that your ajax control return some datas directly from your function you have to use a synchronous method. Without it, datas will be sent from the onreadystatechange event.
Here is a sample how to create a synchronous call for ajax
// Create Namespace
var AppSpace = AppSpace || {};
// Class and Constructor
AppSpace.Tools = function() {
//public methodts
this.test = function(arg) {
return arg
}
this.getData = function(path) {
var xhr_object= new XMLHttpRequest();
// Start synchronous ajax
xhr_object.open("GET", path, false);
xhr_object.send(null);
// Return data
return xhr_object.responseText;
}
}
// Class and Constructor
AppSpace.Presentation = function(initName, initfPath){
//private properties
var configPath = initfPath || 'config.json';
var configData = null;
var name = initName || 'Unnamed Presentation';
//private methods
var getConfigContent = function() {
return tools.getData(configPath);
}
var getConfigData = function() {
return JSON.parse(getConfigContent);
}
//public methodts
//public properties
this.name = null;
this.config = null;
this.debug = null;
//logic
this.name = name;
this.config = getConfigContent();
}
//execution
var tools = new AppSpace.Tools();
var pres = new AppSpace.Presentation('Some Name');
pres.debug = tools.test('value passed')
console.log(pres.debug);
console.log(pres.config);
console.log(pres.name);
First, in this code:
this.getData = function(path) {
var xhr = new XMLHttpRequest();
xhr.open('GET', path, false);
xhr.onreadystatechange = function() {
if (xhr.readyState !== 4) return;
if (xhr.status !== 0 && xhr.status !== 200) {
if (xhr.status === 400) {
console.log("Could not locate " + path);
} else {
console.error("app.getData " + path + " HTTP error: " + xhr.status);
}
return;
}
return xhr.responseText;
};
xhr.send();
}
return xhr.responseText; will not work. It is inside handler function and value will be returned from xhr.onreadystatechange, but not from getData, so you may do something like this:
this.getData = function(path) {
var res;
var xhr = new XMLHttpRequest();
xhr.open('GET', path, false);
xhr.onreadystatechange = function() {
if (xhr.readyState !== 4) return;
if (xhr.status !== 0 && xhr.status !== 200) {
if (xhr.status === 400) {
console.log("Could not locate " + path);
} else {
console.error("app.getData " + path + " HTTP error: " + xhr.status);
}
return;
}
res = xhr.responseText;
};
xhr.send();
return res;
}
Also, this should be like next (you are trying to parse an function, not what it returns)
var getConfigData = function() {
return JSON.parse(getConfigContent());
}
If you'd like to keep it asynchrous you can do something like this. I'd either remove the dest and prop parameters, or the callback, depending on your needs.
this.getData = function(path, dest, prop, callback) {
callback = callback || null;
var xhr = new XMLHttpRequest();
xhr.open('GET', path, false);
xhr.onreadystatechange = function() {
if (xhr.readyState !== 4) return;
if (xhr.status !== 0 && xhr.status !== 200) {
/* ... */
}
dest[prop] = xhr.responseText;
if (Callback) callback(xhr.responseText);
};
xhr.send();
}
//private methods
var getConfigContent = function() {
return tools.getData(configPath, this, 'config', );
}