$.getJSON not doing anything - javascript

I am unsure why, but it seems that when I call $.getJSON after another getJson has been called, nothing happens. Here is the code:
getWeather();
function getWeather() {
$.getJSON("http://where.yahooapis.com/geocode?q=" + lat + ",+" + lon + "&gflags=R&flags=J", function(data){
zipCode = data.ResultSet.Results[0].postal;
WOEID = data.ResultSet.Results[0].woeid;
getYahooWeather(WOEID);
});
}
function getYahooWeather(x) {
var query = escape('select item from weather.forecast where woeid="'+x+'"');
var url = "http://query.yahooapis.com/v1/public/yql?q=" + query + "&format=json&callback=c";
console.log(url);
$.getJSON(url, function(data2){
console.log("hey");
});
}
My question is, am I doing something wrong with these $.getJSON calls?
Thanks so much

You have specified that the callback should be the c function, so declare it:
function getYahooWeather(x) {
var query = escape('select item from weather.forecast where woeid="'+x+'"');
var url = "http://query.yahooapis.com/v1/public/yql?q=" + query + "&format=json&callback=c";
console.log(url);
$.getJSON(url);
}
function c(data2) {
console.log("hey");
}

Your request is outside the current domain. You cannot make foreign request, it is restricted by cross-domain policy.
Such requests and made using a jsonp request instead. And here is a guide to get you started.

Related

Callback function not receiving data after function returns data from API endpoint

On-Click Function
$(".action-open-instruction-confirm").on("click",
function(event) {
var applicationNumber = $('.case-application-number').val();
getInstructionType(applicationNumber, function(data) {
$("#InstructionConfirm #instruction-confirm-instruction-type").html(data);
});
});
Endpoint function
function getInstructionType(applicationNumber) {
if (window.location.port !== "") {
port = ":" + window.location.port;
} else {
return null;
}
var url = window.location.protocol +
"//" +
window.location.hostname +
port +
"-apiEndpoint-?applicationNumber=" +
applicationNumber;
$.get(url,
function(data) {
return data; //<-- Change this to $("#InstructionConfirm #instruction-confirm-instruction-type").html(data); and it works correctly
});
}
HTML
<div id="InstructionConfirm">
<span id="instruction-confirm-instruction-type"></span>
</div>
I have the two functions above that I am trying to use to alter the HTML of the `#instruction-confirm-instruction-type element present in my HTML. The problem is that at the moment the callback function doesn't seem to be functioning properly.
The On-Click function passes the applicationNumber to the getInstructionType function which then calls an API endpoint. This endpoint works correctly and returns the data with no issues. However it then seems like the return data; line in my getInstructionType function doesn't seem to be returning the data properly, as the callback function in the on-click is never executed.
I know the callback is not being executed as it doesn't trigger the breakpoint I have on the $("#InstructionConfirm #instruction-confirm-instruction-type").html(data); line.
If I then replace the return data; line in the second function with $("#InstructionConfirm #instruction-confirm-instruction-type").html(data);, then I get the behaviour I am expecting with no issues.
What exactly is preventing getInstructionType from returning the data to my callback function for it to be used within the on-click function?
The issue is because you don't do anything with the callback you provide. You don't create an argument in the function definition for it, and you don't call it from $.get(). Try this:
$(".action-open-instruction-confirm").on("click", function(e) {
var applicationNumber = $('.case-application-number').val();
getInstructionType(applicationNumber, function(data) {
$("#InstructionConfirm #instruction-confirm-instruction-type").html(data);
});
});
function getInstructionType(applicationNumber, callback) { // accept the 'callback' argument
if (window.location.port !== "") {
port = ":" + window.location.port;
} else {
return null;
}
var url = window.location.protocol + "//" + window.location.hostname + port + "-apiEndpoint-?applicationNumber=" + applicationNumber;
$.get(url, callback); // invoke the callback when $.get receives data
}
Also note that you can just use location.origin instead of manually building the protocol/domain/port string:
var url = window.location.origin + "-apiEndpoint-?applicationNumber=" + applicationNumber;
Although it looks like you may be missing a / after the port as your URL will currently include the string after the port which appears to be incorrect.
Your function doesn't have a parameter for the callback:
function getInstructionType(applicationNumber) {
should be:
function getInstructionType(applicationNumber, callback) {
you can then add your callback
$.get(url,
function(data) {
if ($.isFunction(callback))
callback(data);
});
or even just:
$.get(url, callback)
You might like to consider using promises instead, eg:
$(".action-open-instruction-confirm").on("click",
function(event) {
var applicationNumber = $('.case-application-number').val();
getInstructionType(applicationNumber).done(function(data) {
$("#InstructionConfirm #instruction-confirm-instruction-type").html(data);
});
});
function getInstructionType(applicationNumber) {
....
return $.get(url);

Currency exchange script does not work

for some reason i cant get a value of the JSON, can any body help me?
function forex() {
var to = document.getElementById("to").value;
alert(to);
var from = document.getElementById("from").value;
alert(from);
var amount = document.getElementById("amount").value;
alert(amount);
$.getJSON("http://rate-exchange.appspot.com/currency?from=" + from + "&to=" + to + "&q=" + amount, function (response) {
alert(response);
});
}
Demo
Due to Same Origin Policy, you can't access the resource on rate-exchange.appspot.com via ajax because of your Javascript executing on a different domain.
In your case, this particular site supports JSONP, so you can use jQuery's JSONP implementation to get around the Same Origin Policy. JSONP works by including the target URL as a <script> tag and using a callback, which is not bound by Same Origin Policy.
The $.getJSON() method will use JSONP if it finds a parameter in the URL such as callback=?.
Example:
function forex() {
var to = document.getElementById("to").value;
var from = document.getElementById("from").value;
var amount = document.getElementById("amount").value;
$.getJSON("http://rate-exchange.appspot.com/currency?&callback=?", { from : from, to : to, q : amount }, function (response) {
alert(response.v);
});
}
I also changed your manual URL variables to an object which is preferred because jQuery will handle the URL encoding.
Instead of the below code:
$.getJSON("http://rate-exchange.appspot.com/currency?from=" + from + "&to=" + to + "&q=" + amount, function (response) {
alert(response);
});
use the following code:
$.ajax({
url: "http://rate-exchange.appspot.com/currency?from=" + from + "&to=" + to + "&q=" + amount,
dataType: 'jsonp',
success: function(response) {
alert(response.v);
}
});

using .ajax() in .each()

I'm trying to iterate through elements of .ball class and check if their associated url exists:
$(".ball").each(function(i){
var url;
var c_day = $(this).data('day');
var c_mon = $(this).data('mon');
var c_year = $(this).data('year');
url = c_year + "/" + c_mon + "/" + c_day + ".html";
$.ajax({
url: url,
error: function()
{
alert('file: ' + url + ' does not exist');
},
success: function()
{
alert('file: ' + url + 'EXXXXXXISTS!!!!!');
blogA[ blog_count ] = url;
blog_count++;
$(this).css("color", "red" );
}
});
});
I've done some research and read that using .ajax in .each causes a lot of problems but I couldn't wrap my head around on how to fix it.
The problem is that I get really weird results (has to do with asynchronous?). If I alert url outside of ajax, it correctly iterates through the elements. If I alert url in ajax, it spits out urls that belong to the last element of the class.
Something like this, in order to simplify your code
function successHandler(url, ball) {
return function(ret) {
alert('file: ' + url + 'EXXXXXXISTS!!!!!');
ball.css('color','red')
}
}
var balls = $('.ball'), requests = []
balls.each(function(index, ball) {
var url = ...
requests.push($.ajax({ url : url , success : successHandler(url, ball) })
})
$.when.apply($, requests).done(function() {
alert('all balls are checked')
})
Or with ES6:
const success = (url,ball)=>(ret)=>ball.css('color','red')
const balls = $('.balls')
, reqs = balls.map( (b, i) => {
const url = ...
return $.ajax({url, success:success(url,ball)})
})
$.when.apply($, reqs).done( (resps) => alert('all done'))
A Little explanation: You are blindly using this in your callback, not knowing in which context it is going to be executed. In order to work around it and has your URL into callback we are creating function that returns a function, so it will have URL of current .ball DOM object in the context.
You'll probably also need to execute code after all ajax requests are done, so using $.when is the simplest way of doing it. And we are storing all promises just for this reason.
If you aren't concerned about the order of execution of each ajax call and just want to know when they are all done and the array is fully populated, then you can get this to work by fixing your reference to this and by adding a callback function that is called when all items are done:
// this function called when the ajax calls for all balls have finished
// at this point, blogA and blog_count will be populated
function ballsDone() {
// put your code here
}
var balls = $(".ball");
var cnt = balls.length;
balls.each(function(i){
var url;
var self = $(this);
var c_day = self.data('day');
var c_mon = self.data('mon');
var c_year = self.data('year');
url = c_year + "/" + c_mon + "/" + c_day + ".html";
$.ajax({
url: url,
error: function()
{
alert('file: ' + url + ' does not exist');
if (--cnt <= 0) {
ballsDone();
}
},
success: function()
{
blogA[ blog_count ] = url;
blog_count++;
self.css("color", "red" );
if (--cnt <= 0) {
ballsDone();
}
}
});
});
Keep in mind that the ajax calls are asynchronous so the ONLY place you can use the results from the ajax call is in the success handler. You can't use the results of the ajax calls right after the .each() call in a synchronous fashion because the ajax calls have not yet finished. You must wait for the success handler to be called and when cnt success handlers have been called, then they are all done and you can then process the results.

Request for JSON from externel source using $.getjson. 200 success but where is it?

I'm trying to get weather data from openweathermap. This url works with coordinates I put in, and I can download the JSON when I input the url the in the browser bar. I'm trying to get this working in my page. When I run this code, in Firebug I can see the HTTP request got the 200 success code, but it's not printing the response for some reason. Am I not using getJSON properly?
var url = "http://api.openweathermap.org/data/2.5/forecast?lat="+ position.coords.latitude +"&lon=" + position.coords.longitude;
$.getJSON(url, function(res) {
console.log(res);
});
You are trying to read cross domain JSON in a function which reads JSONP.
Cross domain JSON reading is not possible.
Try a JSONP request instead;, by appending a callback
var url = "http://api.openweathermap.org/data/2.5/forecast?lat=" +
position.coords.latitude +"&lon=" + position.coords.longitude + "&callback=?" ;
$.getJSON(url, function(res) {
console.log(res);
});
JSON response is like this :
{ 'a':22 }
JSONP response is like :
myFunction({'a':22} ) , where myFunction was the value passed as callback
jQuery does not need the name of the callback function, however needs callback to be mentioned in the URL so that it can indentify it as a JSONP request.
JSONP
If the URL includes the string "callback=?" (or similar, as defined by
the server-side API), the request is treated as JSONP instead. See the
discussion of the jsonp data type in $.ajax() for more details.
Append this ?callback=? to the url and try again like:
$.getJSON(url + '?callback=?', function(res) {
console.log(res);
});
Try this
function buildQuery() {
var str = "http://api.openweathermap.org/data/2.5/forecast?lat=27.175009&lon=78.041849";
return "select * from json where url ='" + str + "' ";
}
$.ajax({
url: 'http://query.yahooapis.com/v1/public/yql',
data: {
q: buildQuery(),
format: "json"
},
dataType: "jsonp",
success: function (data) {
alert(JSON.stringify(data));
},
error: function (data) {
consol.log(data);
}
});
working Demo :-
http://jsfiddle.net/HWuDk/1/

Javascript Array loses data

I'm having trouble getting my information into an array in an ajax call, if I alert the information right after I insert it into the array it works fine, but if I do it at the end it alerts unidentified. I made sure that books is declared outside so it doesn't interfere.
var books = [];
$.ajax({
url: 'getFolderContents.php',
dataType: 'json',
success: function (data)
{
for(var i=0;i<data.length;i++) {
var amm = 0;
if(data[i].indexOf(".epub") !== -1) {
//$('#bTable').append("<td><a id = '" + data[i] + "' href = 'book.html'><img src = 'book.png' width = '100px'/><br/>" + data[i] + "</a></td>");
books.push(data[i]);
//alert(books[0]) Works if I call it from here, but not at the end.
}
}
},
error: function()
{
alert("error");
}
});
alert(books[0]);
Your
alert(books[0]);
will be executed while the Ajax call is running and therefore will not have any elements at this point of execution yet. Ajax is asynchronous - while you are doing a request to your PHP script your script continues execution.
Put all actions with books in your success function.
Another hint: As of jQuery version 1.8 you cannot longer use the parameter async: false to create a synchronous "A"jax call. You have to use the callback functions. Have a look at the docs for $.ajax
Your array hasn't lost any data; the data hasn't been put in there yet. The 'A' stands for "asynchronous", meaning your success callback hasn't run yet at the time you call the alert.
Put the alert inside your callback instead:
success: function (data)
{
for(var i=0;i<data.length;i++) {
var amm = 0;
if(data[i].indexOf(".epub") !== -1) {
//$('#bTable').append("<td><a id = '" + data[i] + "' href = 'book.html'><img src = 'book.png' width = '100px'/><br/>" + data[i] + "</a></td>");
books.push(data[i]);
//alert(books[0]) Works if I call it from here, but not at the end.
}
}
alert(books[0]);
},
Your alert is executing before the success function is called. Perhaps seeing the same code using a promise will make things clearer.
$.ajax( url: 'getFolderContents.php', dataType: "json" )
//the then function's first argument is the success handler
.then(function( data ) {
for(var i=0;i<data.length;i++) {
var amm = 0;
if(data[i].indexOf(".epub") !== -1) {
//$('#bTable').append("<td><a id = '" + data[i] + "' href = 'book.html'><img src = 'book.png' width = '100px'/><br/>" + data[i] + "</a></td>");
books.push(data[i]);
//alert(books[0]) Works if I call it from here, but not at the end.
}
alert(books[0]
});
});
I always feel this syntax makes async stuff make more sense. Otherwise this code functions exactly like Blazemonger's correct answer.
Your AJAX call is asynchronous, that's why it is undefined.
The alert at the end happens before the ajax success callback, because ajax is asynchronous.

Categories

Resources