How Can I Get This Jsonp Call To Return A Value?
Solution 1:
the variable rate
has not been defined
$(function() {
getRate('USD', 'PHP');
xRatePHP = rate;
/* Do stuff with rate */
});
after studying your code it seems that rate is defined in the parseExchange(data)
function as
functionparseExchangeRate(data) {
var name = data.query.results.row.name;
rate = parseFloat(data.query.results.row.rate, 10);
alert("Exchange rate " + name + " is " + rate);
}
if you want rate to be accessible from the function namespaces without declaring them from within then the rates would have to specified in the global namespace, which is outside any of the functions or loops.
Edit: The namespace problem has been solved and the answer I've given has been accepted, however I would like to add details about the code you are handling here. It has been taken from the gist here: https://gist.github.com/henrik/265014
We are dealing with JSONP here
the reason why parseExchangeRate
exists and the context of it can seem mysterious at first glance, albeit its existence is the primary connection between your JSONP request and the data returned by the response.
If you take a closer look at the request:
http://query.yahooapis.com/v1/public/yql?
q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2F
download.finance.yahoo.com%2Fd%2F
quotes%3Fs%3DUSDPHP%253DX%26f%3Dl1n'%20and%20
columns%3D'rate%2Cname'&format=json&callback=parseExchangeRate
(I broke the link up into many lines to make it easier to read)
Carefully look at the last segment of the url: callback=parseExchangeRate
This here is the connection, when the JSONP request is complete parseExchangeRate will be called.
So then why did it not work?
Let me display the code once again:
$(function() {
getRate('USD', 'PHP');
xRatePHP = rate;
/* Do stuff with rate */
});
We should break this up:
getRate('USD', 'PHP')
does the job of loading the JSONP with the respective currency types of 'USD' and 'PHP'xRatePHP = rate
assigns the right hand side which israte
toxRatePHP
. But this line gave us a problem! our console pal told us thatrate
is undefined!
The truth: mr.console did not lie, rate
is actually undefined, however mr.console without any further commands given by you a few moments later if asked again would reply that rate
is actually defined. Is this magic?
What is actually happening is that between the time you go from this line
getRate('USD', 'PHP');
to
xRatePHP = rate;
the JSONP response from mr.yahoo hasn't yet come back, which is why when xRatePHP = rate
is issued rate
seems to be undefined.
Hard Code Solution
Let us hard code a duration for our code to wait before using rate
so that we know that mr.yahoo responded, setTimeout
will helps us here:
getRate('USD', 'PHP');
setTimeout(function(){alert(rate)}, 2000);
and everything works now! check the demo at: http://jsbin.com/udikas/1/edit
Soft Code
did you ever consider the case where mr.yahoo takes more than 2000 ms to respond? or maybe even lesser than that? (yahoo is pretty fast!) let us instead take a different approach, this will let us use rate
the exact moment we calculate it with parseExchangeRate
for this we will have to add a callback from parseExchangeRate
:
functionparseExchangeRate(data) {
var name = data.query.results.row.name;
rate = parseFloat(data.query.results.row.rate, 10);
alert("Exchange rate " + name + " is " + rate);
}
to
functionparseExchangeRate(data) {
var name = data.query.results.row.name;
rate = parseFloat(data.query.results.row.rate, 10);
alert("Exchange rate " + name + " is " + rate);
gotTheRate(rate)
}
and then change
$(function() {
getRate('USD', 'PHP');
alert(rate)
});
to
functiongotTheRate(rate){
alert(rate);
}
$(function() {
getRate('USD', 'PHP');
});
a demo of this can be found at http://jsbin.com/udikas/2/edit
Multiple Callbacks (in response to question update)
Remember hard coding setTimeouts
isn't fun, so let us remove that, manageTimer
, q
, and other such elements from your code, instead we can have:
functiongetRate(from, to) {
var script = document.createElement('script');
script.setAttribute('src', "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"+from+to+"%253DX%26f%3Dl1n'%20and%20columns%3D'rate%2Cname'&format=json&callback=parseExchangeRate");
document.body.appendChild(script);
}
functionparseExchangeRate(data) {
var name = data.query.results.row.name;
rateDict[name.match(/USD to ([\w]*)/)[1]] = parseFloat(data.query.results.row.rate, 10);
total_responses++;
if (total_responses === rateArr.length){
for (var k in rateDict){
alert("USD to " + k + " is " + rateDict[k]);
}
}
}
var rate = 1.00;
var timer;
var q;
var rateArr = newArray('PHP','GBP')
var total_responses = 0;
var rateDict = {};
$(function() {
functiongetTheRates() {
for (var x=0; x < rateArr.length; x++) {
getRate('USD', rateArr[x]);
}
}
getTheRates();
});
http://jsbin.com/udikas/4/edit
-Relfor
Solution 2:
You should re order your code flow:
functiongetRate(from, to) {
var script = document.createElement('script');
script.setAttribute('src', "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"+from+to+"%253DX%26f%3Dl1n'%20and%20columns%3D'rate%2Cname'&format=json&callback=parseExchangeRate");
document.body.appendChild(script);
}
functionparseExchangeRate(data) {
var name = data.query.results.row.name;
var rate = parseFloat(data.query.results.row.rate, 10);
alert("Exchange rate " + name + " is " + rate);
xRatePHP = rate;
/* Do stuff with rate */
}
$(function() {
getRate('USD', 'PHP');
// rate is not yet available here, so don't do anything with it
});
Solution 3:
try to put:
var rate = 0;
on top of your code. This will fix the error. Then you have to consider that if you get 0 maybe you are reading the variable at the wrong time, before it gets populated.
Post a Comment for "How Can I Get This Jsonp Call To Return A Value?"