Why doesn't simple google web search through getJSON always work? - javascript

This simple web search through google API is shaky. Sometimes it returns the 4 first findings (as it should), sometimes JSON thinks its a "success" but the responseData is null. Why am I getting these inconsistencies? Is it a asyncronic problem? How do I make it more stable? (When I search for images on google it is rock stable)
var baseUrl = "https://ajax.googleapis.com/ajax/services/search/web?v=1.0&start=0&q=";
var searchTerm = "obama"; //Lots of hits
$(document).ready(function() // don't do anything until the document is loaded.
{
$.getJSON(baseUrl + searchTerm + "&callback=?", function(json) // call getJSON providing the complete url with search term and a JSONP callback
{
$.each(json.responseData.results, function(i, gResults){
console.log("title: " + gResults.titleNoFormatting);
});
});
});
When it fails I find this in the json data structure:
json.responseDetails: "Suspected Terms of Service Abuse. Please see
http://code.google.com/apis/errors"
So Google think I'm attacking it with too many requests. Do I have to set an API key? right now I just include the
<meta name="google-site-verification" content="myAPIkey-Herevbng66r" />
But I'm running on my local computer so maybe it doesn't help…

Try this:
function(json) // call getJSON providing the complete url with search term and a JSONP callback
{
if (json.responseData === null)
console.log("json returned nothing");
else
$.each(json.responseData.results, function(i, gResults){
console.log("title: " + gResults.titleNoFormatting);
});
});
});

Related

JQuery - Ajax get Request - doesn't return me the "extracts" or "exintro" (summary) property in the response

In general I'm working on a little webapp that just shows me search entries from wikipedia on the page after I enter a search term into the textfield.
I’m working on this problem a long time now.
I have setup an ajax get request to the wikipedia api.
It’s working fine as far as the title goes. But I looked at the json I get in return via console.log and see that there is no summary or first paragraph in this response.
So I googled and found a very nice article which points me to that link:
(can't post it due to under 10 reputation, sad story)
Just google for "wikipedia extracts api"
It says that the query also needs this prop=“extracts” and the exintro: true
But if I add this to my query I do not get the "exintro" in return.
Here is how I set up my ajax call:
function callback(){ // gets called when sliding up the div is completed
$.ajax({
url: 'http://en.wikipedia.org/w/api.php',
//TODO: Fix this line of code (extracts)
data: { action: 'query', list: 'search', prop: 'extracts', exintro: true, srsearch: $("input[name=search]").val(), format: 'json' },
dataType: 'jsonp',
success: processResult
});
$(".container").remove();
}
So if it’s successfull it runs the processResultmethod:
function processResult(apiResult){
console.log(apiResult);
for (var i = 0; i < apiResult.query.search.length; i++){
$('#display-result').append('<div class="' + i + '">' + '<p>'+apiResult.query.search[i].title+'</p>' + '<p>'+ apiResult.query.search[i].snippet +'</p>' + '</div>');
}
}
But the json it returns looks something like that:
Picture of the returned json
Nothing I’m interested in. I need the summary or exintro how wiki api calls this.
Here is the link to the github: https://github.com/dhuber666/wikipediaJS
Any ideas? Do I set it up wrong in the ajax call object “data” ? Pleae help!
The snippetin the json is useless since it cuts off the sentence after a few words
Your "data" object is fine. Seems like "snippet" is just what Wikimedia API returns for this request. You can then send request to get extracts of returned pages (using "title" or "pageid" you get for each article). For example: https://en.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro=true&explaintext=true&titles=Title|Hello for titles "Title" and "Hello".
Maybe this other API call will suit your needs:
https://en.wikipedia.org/w/api.php?action=opensearch&search=hello&format=json It returns one full sentence, doesn't cut anything.

Convert jQuery.ajax code to accept pagination

I'm trying to take code which I found on a website's blog regarding using javascript and REST to create charts in SharePoint. The original article can be found here for reference -- http://www.cardinalsolutions.com/blog/2013/05/building_charts_ins -- I've already tried reaching out to the writer asking for help but I haven't gotten a response.
"use strict";
var EngagementChartBuilder = window.EngagementChartBuilder || {};
//The module for executing a REST query
EngagementChartBuilder.RESTQuery = function (listTitle, query) {
var execute = function (listTitle, query) {
var restUrl = _spPageContextInfo.webServerRelativeUrl +
"/_api/web/lists/getByTitle('" + listTitle + "')/items";
if (query != "") {
restUrl = restUrl + "?" + query;
}
var deferred = $.ajax({
url: restUrl,
type: "GET",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
}
});
return deferred.promise()
};
return {
execute: execute
}
}();
When this code executes, though, it only returns the first 100 results due to SharePoint's pagination. I found articles/posts which points me in the direction of using the data.d.__next into the URL and re-run the AJAX query, but trying to understand this JavaScript code is really making my head spin.
I thought I could do a do-while loop but I'm really not making any progress.
Any help would be immensely appreciated. Thanks in advance.
You can add $top and $skip parameters to your endpoint URL (in your case, the restUrl string) to specify how many items to retrieve and how many items to skip respectively.
Use the $skip=n parameter to skip the first n entries according to the $orderby parameter
Use the $top=n parameter to return the top n entries according to the $orderby and $skip parameters.
To page through results, you just need to update the $skip token and requery.
The following example gets items in batches of 1000:
var endpointUrl = "/_api/lists('guid')/items";
$.getJSON(
endpointUrl + "?$orderby=Id&$top=1000",
function(data){
processData(data); // you can do something with the results here
var count = data.d.results.length;
getNextBatch(count, processData, onComplete); // fetch next page
}
);
function getNextBatch(totalSoFar, processResults, onCompleteCallback){
$.getJSON(
endpointUrl + "?$orderby=Id&$skip="+totalSoFar+"&$top=1000",
function(data){
var count = data.d.results.length;
if(count > 0){
processResults(data); // do something with results
getNextBatch(totalSoFar+count, callback); // fetch next page
}else{
onCompleteCallback();
}
}
);
}
Integrating that concept with jQuery deferreds is another matter.
I recommend you either:
take some time to learn about the functionality encapsulated in jQuery deferreds so that you can use them effectively, or
abandon deferreds entirely and just use your own asynchronous functions with callbacks, as in the documentation example
$skip does not work in SharePoint 2013/ SharePoint line OData REST.
There is a property in the SharePoint REST API response named "__next" that you can use to implement pagination.
This link contains "$skiptoken", that is useful for pagination.
I think you should try to implement the following way :
Use $filter -->
/_api/web/Lists/GetByTitle(ListTitle)/items?$filter=Id gt {valueSkipFrom}&$top={ValueTop}
Use "__next" link. This can be accessed as "response.d.__next"
If it has a value, it contains the url that will return the next set of items. If it's null, you've hit the end of the result set
Please refer this link that will be guide you : https://sharepoint.stackexchange.com/questions/74777/list-api-get-all-items-limited-to-100-rows

Using USDA REST API

I can't seem to figure out how to use USDA REST API no matter how hard I try. I've taken about 6 different online tutorials on how to use REST APIs all of which do not work with this particular API (I'm sure it's something small I'm missing but I've wasted countless hours doing/watching tutorials with no success).
Here's the link to their API:
https://ndb.nal.usda.gov/ndb/doc/apilist/API-FOOD-REPORT.md
Here's what I'm typing in my JavaScript:
xhr = new XMLHttpRequest();
xhr.open("GET", "http://api.nal.usda.gov/ndb/reports/", true);
console.log(xhr.status);
The API says to pass your API KEY in parameters, but that makes no sense to me as every single tutorial I have read does not explain how to pass a KEY as a parameter... If someone would mind taking a moment to write the code necessary to access this API I would be greatly indebted.
UPDATE: I've also tried the JQuery method as follows:
$.get(
"http://api.nal.usda.gov/ndb/reports",
{
"api_key": "API KEY",
"ndbno": "01009"
},
function(data) {
console.log(data);
}
);
With no luck.
UPDATE 2: After leaving the JQuery example in for about 5 minutes, I get an error in the chrome console that says:
XMLHttpRequest cannot load http://api.nal.usda.gov/ndb/reports?api_key=(my API KEY)&ndbno=01009. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 403.
FINAL UPDATE: Problem was with my ISP apparently. Need to deal with that :(
The document you reference has a sample request URL:
http://api.nal.usda.gov/ndb/reports/?ndbno=01009&type=b&format=xml&api_key=DEMO_KEY
You just need to replace the ndbno, type, format and api_key values (the bits that come after the "="). For instance if your API key was 12345, you would need to change it like so:
http://api.nal.usda.gov/ndb/reports/?ndbno=01009&type=b&format=xml&api_key=12345
A complete, albeit "poor", implementation would be:
var apiKey = "DEMO_KEY";
var ndbno = "01009";
var type = "b";
var format = "json";
var url = "http://api.nal.usda.gov/ndb/reports/?ndbno=" + ndbno + "&type=" + type + "&format=" + format + "&api_key=" + apiKey;
$.get(url, function( data ) {
alert( "Data Loaded: " + JSON.stringify(data) );
});
Using the 'DEMO_KEY' provided by USDA I can get back a JSON result using the following code pasted into an HTML file (based on code from your on-going discussion with #BlakeH):
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$( function() {
$.get(
"http://api.nal.usda.gov/ndb/reports",
{
"api_key": "DEMO_KEY",
"ndbno": "01009"
},
function(data) {
console.log(data);
console.log( JSON.stringify(data, null, ' '))
}
);
});
</script>
No issues with CORS were encountered with this code.
Is there any chance that you submitted more than 1000 requests in the past 24 hours?

AJAX and JSON error handling

I have a form which submits data via AJAX to an external server.
The data which gets sent is then validated and if correct the user can then advance onto the next step of the form.
If the data is not valid, then the server returns an error which is outputted as a JSON object.
I can see the JSON object in FIDDLER.
My aim is to grab that JSON data and output it on the page and notify the user.
Ideally, i would do this as part of an error handler on the AJAX request(found below).
Is this achievable?
PS:
Unfortunately, I can't set up a demo because the link that the data is posted to is only available on my network.
It is also worth pointing out that the error that the back-end script outputs is actually stored in the link that the data is posted to.
AJAX REQUEST:
var setUpVrmData = function() {
$("#getvrmdata").click(function () {
var p_vrm = $('#p_vrm').val();
$.ajax({
dataType: "JSON",
type: "POST",
url: "http://217.35.33.226:8888/l4_site/public/api/v1/BC8F9D383321AACD64C4BD638897A/vdata",
data: {
vrm: p_vrm,
},
success: function(data) {
//Empty the dropdown box first.
$("#p_model").empty();
appendString = "<option value='none'>-- Select your model --</option>";
$.each(data['vehiclemodel'], function (k, v) {
// += concatenate the string
appendString += "<option value='" + k + "'>" + v + "</option>";
});
$("#p_model, #ent_mileage").show();
$('.js-find-my-car').hide();
$('.js-get-price').show();
$("#p_model").append(appendString);
$("#p_model").prop("disabled", false);
$('#skey').val(data['skey']);
},
error: function() {
console.log("We return error!");
}
});
});
The Error function will return an XHR object that you may be able to parse to get the message you want. I don't know what is serving the data so depending on how that's setup your mileage may vary. I've done this using PHP as well as C# and writing to Console, but in both cases I was able to control the returned data.
I used this article : http://encosia.com/use-jquery-to-catch-and-display-aspnet-ajax-service-errors/ as a starting point.
You'll need to update:
error: function() {
console.log("We return error!");
}
to
error: function(xhr, status, error) {
console.log("We return error!");
}
Set a break point there in Firebug to check if an XHR object is passed, if not you'll need to find a way to get it.. You mention you can see the JSON in fiddler, it should be available to you. If it is, just use the eval posed in the article and you should be okay. If not you'll have to go and figure out how to get it, depending on your platform difficulty will vary.
A few things to note, eval is messy and can get you into trouble. In the cases I've done this, I removed the eval in production.
Also as of jQuery 1.8 success error and complete are deprecated. Use done fail and always if you plan on updating jQuery in the future.
jQuery API reference, for reference.
http://api.jquery.com/jquery.ajax/

Rendering mongodb database results from POST request in .ajax jquery wrapper in node js

I am creating a basic piece of functionality to allow users to send their location to a server which then queries a database and returns locations near to them. I am using the below jQuery .ajax wrapper to POST data to the server. This takes the form of a latlon point which is then used as the basis for a geosearch in MongoDB using nodejs and express on the backend. The results of the search are then intended to be returned to the client and rendered by the createMapListings function.
The /find page is initially rendered through a GET request to the database via mongodb separate from the below code. However subsequent to initial rendering, I then want to return results dependent on the location provided.
The POST method works fine and the location is posted to the server, with the search results being returned as I can print contents out through the console log.
However, I then want to render the results on the client-side. As mentioned, the results of the search render in the console, but when I attempt to pass through to the client, I can render the data itself (in the form of an array of objects) in the #output div, but the createMapListings function does not seem to catch the data.
In fact, the below function appears to be called but prints out over a thousand rows with the data that should be caught described as 'undefined'. I have tried to use res.render and res.redirect, but in the first case, the view renders in the div (which I suppose is expected) and the redirect fails.
The createMapListings function works fine when a simple GET request is made to the server, for example, for all objects in a collection, using ejs template. However, I think the issue here may be a combination of a POST request and then wanting to pass the results back to the AJAX request using the complete callback.
I apologise if the below code is somewhat obtuse. I’m definitely what you would call a beginner. I appreciate the above functionality may not possible so if there is a better way, I would of course be open to it (res.direct perhaps).
Here is the relevant client side script:
$(document).ready(function(){
$("#geolocate").click(function(){
navigator.geolocation.getCurrentPosition(geolocate, function(){
});
});
});
function geolocate(pos){
var latlonpt = [];
var x = pos.coords.latitude;
var y = pos.coords.longitude;
latlonpt.push(x);
latlonpt.push(y);
var obj = {
userlocation: latitudelongitudept
};
$.ajax({
url: "/find",
type: "POST",
contentType: "application/json",
processData: false,
data: JSON.stringify(obj),
complete: function (data) {
$('#output').html(data.responseText);
$('#infooutput').children().remove();
createMapListings(data.responseText);
}
});
};
function createMapListings(maps) {
for (var i = 0; i < maps.length; i++) {
var url = maps[i]._id;
var fullurl = "<a href='/show?id=" + url + "'>Route</a></div>";
var title = "<div>" + maps[i].title + " - " + fullurl +"";
$('#infooutput').append(title);
};
};
</script>
Here is the relevant route used in a basic express app to handle the post request made by the above .ajax wrapper.
exports.findbylocation = function(req, res) {
console.log(req.body.userlocation);
var userlocation = req.body.userlocation;
Map.ensureIndexes;
Map.find({loc :{ $near : userlocation }}, function(err, maps) {
if (err) {
console.log(err)
}
else {
var jmaps = JSON.stringify(maps);
console.log(jmaps);
res.send(jmaps);
}
});
};
By convention, the data variable name in an $.ajax callback signature refers to the parsed HTTP response body. Since your callback is on complete, we're actually passed the XMLHttpRequest used, by convention called xhr. You rightly grab the responseText property, but this needs parsing to be useful. So long as we take care over our Content-Type's and don't explicitly disable processData, jQuery will do the encoding/unencoding for us - we just deal with objects. This is a good thing, since the transport format isn't usually of any particular importance to the application logic. If we use res.json(maps) in place of res.send(jmaps), we can write our call more simply:
$.ajax({
url: '/find',
type: 'POST',
data: obj,
success: function(data) {},
error: function(xhr, text, err) {}
});
Here data is a Javascript object already parsed and ready to use. We also use a default application/x-www-form-urlencoded request rather than explicitly setting a contentType. This is the same as far as express is concerned: it will just be parsed by urlencoded instead of json.
Assuming you solved your client-sie problem.
As you are using express there is no need for JSON.stringfy,
you can use res.json(maps).

Categories

Resources