I know very little (none) JavaScript, or much about using API's. However I would like to display some hotel reviews on my webiste made available over the qype.com API. However I'm struggling with being able to manage this.
This is the code I have so far:
$(document).ready( function() {
$.getJSON( "http://api.yelp.com/business_review_search?term=hilton%20metropole&location=B26%203QJ&ywsid=APIKEY Removed",
function(data) {
$.each( data.businesses, function(i,businesses) {
content = '<p>' + businesses.reviews.text_excerpt + '</p>';
content = '<p>' + businesses.reviews.date + '</p>';
$(content).appendTo("#review");
} );
}
);
} );
I have a div in the body called review where I want to display the text.
Any advice greatly received.
JSON can be found at http://api.yelp.com/business_review_search?term=hilton%20metropole&location=B26%203QJ&ywsid=lOoGGbkYpVmTvxHlWGT2Lw
Also, I have multiple businesses on the same page, how would I make use of this multiple times on the same page, but output the data in different locations?
Update: Ah, I see your error now. businesses.reviews is an array (each business can have more than one review) so you have to loop over each business and each business' reviews.
i had to change some things to get it to run in my test bed, but you can see a sample of this code running here: http://bit.ly/4mTxPp
yelp currently support JSONP calls so you can change your code to:
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
function showData(data) {
$.each(data.businesses, function(i,business){
// extra loop
$.each(business.reviews, function(i,review){
var content = '<p>' + review.text_excerpt + '</p>';
content += '<p>' +review.date + '</p>';
$(content).appendTo('#review');
});
});
}
$(document).ready(function(){
// note the use of the "callback" parameter
writeScriptTag( "http://api.yelp.com/business_review_search?"+
"term=hilton%20metropole"+
"&location=B26%203QJ"+
"&ywsid=lOoGGbkYpVmTvxHlWGT2Lw"+
"&callback=showData"); // <- callback
});
function writeScriptTag(path) {
var fileref = document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", path);
document.body.appendChild(fileref);
}
</script>
Do you get an error in Firebug using this code? What happens exactly?
I expect this problem is caused by the fact that you're trying to do a cross-domain request which is not allowed. Normally you'll want to do this kind of data gathering on your back-end, but you can use an alternative such as JSONP to do the same.
Take a look at jQuery's documentation on this stuff and it should be clear what's going on.
Also, as a side note: In your callback you have content = which is ok but not ideal. Assigning to content like this will create a variable in the global scope which you do not want. In this case it probably wont cause an issue but say you have 2 of these requests going at once, the second assignment could easily step on the first causing hard-to-debug weirdness. Best to just always create variables with var.
If data.businesses is an array, I would assume that data.businesses[x].reviews is also an array. This code loops the businesses as well as the reviews for each business. It also gets rid of the content variable by appending straight to the #review div.
$.each(data.businesses, function(i,business){
$.each(business.reveiws, function(r,review){
$("#review").append(
'<p>' + review.text_excerpt + '</p>'
).append(
'<p>' + review.date + '</p>'
);
});
});
I think you can specify JSONP with your $.getJSON method by adding "callback=?" to the url parameters.
As of jQuery 1.2, you can load JSON
data located on another domain if you
specify a JSONP callback, which can be
done like so: "myurl?callback=?"
$.getJSON("http://api.yelp.com/business_review_search?term=hilton%20metropole&location=B26%203QJ&ywsid=APIKEY Removed&callback=?",
function(data){
...
});
The problem is that you are making a cross domain request, which is not allowed for security purposes. Either you will have to make a proxy script on your domain (like for example in php) and call yelp from that or fetch the data completely on the server side.
I assume you must be experiencing part of your data (which you are supposed to see) disappearing. I think you must edit your code to:
content = '<p>' + businesses.reviews.text_excerpt + '</p>';
content += '<p>' + businesses.reviews.date + '</p>';
Hope this helps...
Related
I'm trying to add entries to a dropdown list which I have defined in my .jade file as below.
extends layout
block content
script(src='http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js')
script(src='/javascripts/addsystem.js')
h1= title
p Testing
select#allSystems
And my Ajax method looks like the following:
var select = $('#allSystems');
console.log("Runing script")
$.ajax({
url: '/submit/getAllSystems',
dataType:'JSON',
success:function(data){
$.each(test.system, function(key, val) {
select.append('<option id="' + val.id + '">' + val.name + '</option>');
})
}
});
The Ajax script is located the JS file which is included in the Jade file. (Jquery is also included in the Jade file).
Everything seems to be working fine, except for the append. I.e. the console logs show good data all the way and when printing the select object in the Ajax script the browser recognizes it as a HTML element.
When printing the running "console.log(select);", Firefox console shows the following:
Object { context: HTMLDocument → submit, selector: "#allSystems" }
Any idea what I'm doing wrong?
Jade is a templating language that has to be compiled and executed with the data in order to render HTML. JQuery will not automatically do that for you, which is why your commented-out attempt at select.append failed.
Building the HTML yourself works (though it makes some ugly code and I still dislike string concatenations). However, when you did that you changed to .appendTo, which is going to try and take your select object and append it to the option, which I don't think is what you want.
give this a shot:
select.append('<option id="' + val.id + '">' + val.name + '</option>');
If that doesn't work, then there's something up with your selector that gets you the select variable.
* EDIT *
I notice in your Jade that you are loading your scripts before the rest of the DOM. IF the contents of addsystem.js are as you describe, then you're fetching the data and trying to append it to a DOM node that doesn't exist yet. Try wrapping it like so:
$(function(){ /** your code **/ })
Which is a shorthands to jQuery's methods for doing stuff after the DOM is fully loaded.
I am trying to read the google calendar events from the JSON response but nothing happens.
I have tried the code from here but that too is not working. I am adding the code to my CMS and when I check on the front end, nothing appears. I even tried running this fiddle http://jsfiddle.net/bGdhD/ but this also doesn't provide any response.
My google calendar URL is
https://www.google.com/calendar/feeds/varun.luthra.72%40gmail.com/public/full?alt=json-in-script&max-results=25&singleevents=false&futureevents=true&sortorder=descending&orderby=starttime
<script>
var event = '';
var gclaData = 'https://www.google.com/calendar/feeds/varun.luthra.72%40gmail.com/public/full?alt=json-in-script&max-results=25&singleevents=false&futureevents=true&sortorder=descending&orderby=starttime';
$.getJSON(gclaData,function(data){
$.each(data.feed.entry, function(i, entry){
event += '<div class="eventHolder">';
event += '<div class="eventTime">'+ entry.gd$where[0].startTime+"</div>";
event += '<div class="eventName">'+ entry.title.$t + "</div>";
event += '<div class="eLink">'+ entry.link[0].href + "</div>";
event += '</div>';
});
$('#output').html(event);
});
</script>
<div id="output"></div>
Also, could this be a cross domain issue?
It's not a cross domain problem, because the response includes the Cross Origin Resource Sharing header:
access-control-allow-origin:*
The problem is the response is a JSONP response and so includes a callback function. This makes it invalid JSON (unless you strip the callback).
Option 1: If you set &callback=? in the URL, jQuery will treat the response as JSONP:
var gclaData = 'https://www.google.com/calendar/feeds/varun.luthra.72%40gmail.com/public/full?alt=json-in-script&max-results=25&singleevents=false&futureevents=true&sortorder=descending&orderby=starttime&callback=?';
Option 2: Use $.ajax() and strip the callback:
gdata.io.handleScriptLoaded(
Also strip the closing parenthesis and semicolin );. This leaves you with a valid JSON response, which needs to be decoded from a string to a Javascript object using JSON.parse() or similar.
Also, there doesn't appear to be an entry array or object in the response, so you need to modify your success event accordingly.
Last point, this will not work:
entry.gd$where[0]
If the variable name has special characters, use the [] notation:
entry['gd$where'][0]
Recently I use $.getJSON to send request to flickr api to get some photo info (I got 100 data totally)
and in $.getJSON()'s callback function, I use $.each() and $.get('myServlet.do') to send data to servlet then insert into MySQL database.
I think it should be no problems, but I found that my database would have duplicated data if I use the method above, does anyone know what is the problem?
the data is duplicated when servlet received, btw.
it would be very appreciated if someone can give me some advice...
this is my code that how I using $.get() :
$.getJSON('http://query.yahooapis.com/v1/public/yql?q=select id,title,location.latitude,location.longitude,dates.taken,farm,server,secret from flickr.photos.info where photo_id in' + '(select id from flickr.photos.search(0) where text=\"' + queryText + '\" and has_geo=1 and lat=22.993299484253 and lon=120.20359802246 and content_type=1 and radius=20 and api_key=\"' + appid + '\" limit 100 ) and api_key=\"' + appid + '\"&format=json',
function (data) {
var clientTime = $('#clientTime').html();
$.each(data.query.results.photo,
function () {
console.log(this.id + " " + this.title + " " + this.farm + " " + this.server + " " + this.dates.taken);
$.post('insertphotoinfo.do', {
id: encodeURI(this.id),
title: encodeURI(this.title),
farm: encodeURI(this.farm),
server: encodeURI(this.server),
secret: encodeURI(this.secret),
takendate: encodeURI(this.dates.taken),
latitude: encodeURI(this.location.latitude),
longitude: encodeURI(this.location.longitude),
clientTime: encodeURI(clientTime)
},
function (Result) {
});
});
I'm afraid I know nothing about servlets, but I can address this from a MySQL perspective.
At a very simple level, if you are picking up the same data from Flickr each time, and then inserting all that data into a database, you will end up with duplicate data.
An INSERT command, however it is wrapped up, adds a row of data. It does not check to see if that data already exists.
In abstract, there are three solutions to your problem.
1) Write something that checks if an item already exists and then run UPDATE or INSERT as appropriate.
2) If you always collect a full set of data, and you have nothing that is dependent on an ID column, you could remove all the existing data before you insert the new data. If it is the only data in the table, you can use TRUNCATE.
3) Mark an appropriate column in MySQL as being UNIQUE. This will prevent another row being added with the same data - but your servlet may not like being passed an error.
The simplest is solution 2.
You will have to figure out yourself how any of these solutions is achieved with servlets, but armed with the right concepts you should be able to find something.
I am creating dynamic sites with the same code base, where I will need to display the appropriate Google ads Javascript code, based on some logic.
In my .Net 4, MVC3 environment, I have setup the following scenario:
Navigating to www.mysite.com/script_processor/ returns the following text:
function doAlert(v1, v2){alert('Called alert()' + v1 + ' : ' + v2);}
This text come out of my model as such:
page.stringResponse = "function doAlert(v1, v2){alert('Called alert()' + v1+ ' : ' + v2);}";
I can then do something like this from a separate site/page:
<script type="text/javascript" src="http://mysite.com/script_processor/">
</script>
<script type="text/javascript">
doAlert('string 1', 'string 2');
</script>
As you would expect, I get an alert box with "Called alert() string 1 : string 2", so the function on mysite.com is accessible from site 2.
Obviously when I do a view source form the page, I only see the doAlert() call, and not the content of the function that sits on mysite.com.
Now, instead of doAlert() on mysite.com, I want to have a function that dynamically writes out javascript that can will be seen on site 2 when it's called.
I created a model method:
public GetResponsePage GetPageResponse(string V1, string V2)
{
var page = new GetResponsePage();
page.stringResponse = "<script type=\"text/javascript\">document.write('testing injected Javascript.');alert('value of v1: " + V1 + "value of v2: " + V2 + "');</script>";
return page;
}
When navigating to the route, I see the popup, and the "testing injected Javascript." on the page.
When I reference this from site 2, I don't see the popup, nor do I see "testing injected Javascript" in the page source.
As I mentioned I will later replace this with the JS code for the appropriate Google Ads js code.
I don't think this is working quite right... what am I missing?
Thanks.
You can use the ever evil eval to dynamically execute JavaScript. The JavaScript you pass in can also declare functions.
eval("function doAlert(v1, v2){alert('Called alert()' + v1 + ' : ' + v2);}");
I'm not sure exactly what you're trying to accomplish, but you could put an eval call like this wherever you want:
function createDoAlertFunction(){
eval("function doAlert(v1, v2){alert('Called alert()' + v1 + ' : ' + v2);}");
}
Just note though, that this should be avoided. Stick to declaring your functions the old fashioned way, like you already are.
EDIT
Oh, you want MVC to to inject JavaScript dynamically. MVC has a JavaScriptResult, but it looks like its use is strongly, strongly discouraged.
Nonetheless, here's a link that shows its use
public ActionResult DoSomething() {
string s = "$('#some-div').html('Updated!');";
return JavaScript(s);
}
and why it's not a good idea
I know it is very late. But there is very easy way to send JavaScript from controller.
#Html.Raw("<script>" + #ViewBag.DynamicScripts + "</script>")
In controller send JavaScript as follows:
ViewBag.DynamicScripts = "alert('test');";
I have a fly out javascript menu that is initialized using the onload event. All of the data inside the menu right now is hard coded but needs to be dynamic and will come from my database. Is there a way to build this javascript file with my database values? Is this possible? I'm a total noob to JS so please spell things out for me.
Maybe an example of what I'm thinking will help. This is part of my JQuery file after I have my serialized array. How do I get the array into the menu from here?
if(data.success == 0) {
// error
} else {
// my array that needs to be exported into the JS file.
}
This is the other file that I'm talking about that needs to be built with the data from the database.
function create_menu()
{
document.write(
'<table cellpadding="0" cellspaceing="0" border="0" style="width:98%"><tr>' +
'<td class="td" valign="top">' +
'<h3>Test</h3>' +
'<ul>' +
'<li>afd</li>' +
'<li>fsg</li>' +
'<li>sfg</li>' +
'<li>fsg</li>' +
'</ul>' +
'</td></tr></table>');
}
One option would be to build the JavaScript file dynamically on the server when a request comes in from the browser using one of the various server-side scripting languages. The downside to this method is that that browsers may cache the file and, therefore, may operate with stale data.
The other option is to use a static JavaScript file and use an AJAX call to get the latest menu options and then render them into the page's DOM. This would be better than the first option since you wouldn't have the caching concerns.
The third method is to dynamically generate the markup for the page and not worry about requesting a menu via JavaScript. This is the best option in my book. I wouldn't want to wait for the navigational elements of a page to be requested via JavaScript when it's something simple that should already be part of the page.
You need to use AJAX.
You can load the contents from back-end into a JavaScript array and use that. This is how dynamic data is fetched from the server without a page refresh.
Hope this helps.
JSON is a data format which can be executed using eval(). Create some JSON which represents whatever format you've hard-coded and evaluate it like in Wikipedia's example
This is only okay if you trust the source of the JSON, in this case you're generating it yourself so it should be okay.
example, json_menu.php returns the text:
create_menu( { "menus" : ["afd", "fsg", "sfg", "fsg"] } );
And you execute it like this by evaluating it:
function create_menu(JSONData)
{
var s = '<table cellpadding="0" cellspaceing="0" border="0" style="width:98%"><tr>' +
'<td class="td" valign="top">'
// loop through each one
for(var menu in JSONData.menus)
s = s + '<li>' + menu + '</li>';
s = s + '</ul></td></tr></table>';
// write it out
document.write(s);
}
// this gets called somewhere in your OnLoad
function yourOnLoader()
{
var ajaxRequest = new ajaxObject('http://your-site.com/json_menu.php');
ajaxRequest.callback = function (responseText) { eval(responseText); }
ajaxRequest.update();
}