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?
Related
I'm trying to retrieve data from json ('.cfm') file. I tried different solutions and still unable to fix the error. I found a solution on stack over flow about using XMLReader, but does that work when reading data from json file? I also tried to use HttpClient.GetAsync() method with the same result.
According to the API document, caller must set a header “Authorization” to the value of an agreed upon token. The web service has one required parameter. The method of access is via GET request. Here is the screenshot of my code in c#.
Uri with parameters: https://www.aopa.org/webservices/USAlliance/api.cfm?customerId=10180072
I also tried getting the result with jquery ajax call, which is as follows: (here I tried putting latest jquery library as 'src' value, secondly, instead of 'complete' I tried 'success' variable, then I found 'done' function on internet, that also did not work out)
function btn_p1_clientFunction() {
console.log("btn_p1_clientFunction is called!");
javascript: window.scrollTo(0, 0);
var token = 'USA11!anc3';
var memberID = $('#txtAOPAMemberNum').val();
var client = "https://www.aopa.org/webservices/USAlliance/api.cfm?customerId=" + memberID;
$.ajax({
url: 'https://www.aopa.org/webservices/USAlliance/api.cfm',
headers: { 'Authorization': token },
data: {
"message": $(this).val(),
"status": $(this).val(),
"master_customer_id": $(this).val(),
"member": $(this).val(),
},
complete: function () {
alert(this.headers.Authorization);
}
});
$.get(client, function (data, status) {
alert("Message: " + data.message + "\nStatus: " + data.status + "\nMember ID: " + data.master_customer_id + "\nMember: " + data.member);
});
}
The alert displaying header 'Authorization', gives correct value. The output alert displaying data object from json (cfm) file, is producing unwanted results.
Message: Authorization missing or invalid.
Status: ERROR
Member ID: undefined
Member: undefined
Also, when tested in Postman, output is what I want. After which I'm sure, something is wrong in my way of programming.
{
"message": "",
"status": "OK",
"master_customer_id": 10180072,
"member": true
}
Please, help me in resolving the issue. I have been trying both ways (c# and jquery) since weeks.
You Authorization should be in format of:
'Authorization':'Basic xxxxxxxxxxxxx'
Please do check if token value follows the format
#praty The solution didn't work out. However, I tried removing the data variable block and XMLReader commands and now its working as required. Working code
I am making a weather website for my school project using the Wunderground Weather API. This is the code I am using to get the JSON data:
$.getJSON("http://api.wunderground.com/api/<apikey>/conditions/q/" + wlocation + ".json", function(data){
alert(data);
});
The <apikey> is where I put my API key, and the $ character is just a shortcut for JQuery.
When I open this webpage, which is local, not published, no alert pops up and I get the error:
XMLHttpRequest cannot load http://api.wunderground.com/api/<apikey>/conditions/q/<myzipcode>.json. Origin null is not allowed by Access-Control-Allow-Origin.
After doing some research on this error, it sounds like I might have to create a web server. However, for the project, we need to turn it in as a folder of .html and other "web files". Is there another way to do this or do I have to make a web server? This project is due soon, so any help is appreciated!
Yes, you can use JSONP for this.
I'm not sure if Wunderground Weather API have some kind of callbacks in JSON. But if they do even jQuery getJSON support JSONP.
Seems like you run into Same origin policy.
here is a code sample from the link that you provided in your original post (http://www.wunderground.com/weather/api/d/docs?d=resources/code-samples). they use JSONP. yes, as #antyrat said, it is a CORS problem.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script>
jQuery(document).ready(function($) {
$.ajax({
url : "http://api.wunderground.com/api/Your_Key/geolookup/conditions/q/IA/Cedar_Rapids.json",
dataType : "jsonp",
success : function(parsed_json) {
var location = parsed_json['location']['city'];
var temp_f = parsed_json['current_observation']['temp_f'];
alert("Current temperature in " + location + " is: " + temp_f);
}
});
});
</script>
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).
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);
});
});
});
So I need to make a a cross domain request where the response is not JSON formatted, so I cannot use .getJSON. .get obviously doesn't work because it is a cross domain request.
I came across this (Read this) when I was googling and it seems it should work for what I want to do (which is do a cross domain call that isn't json formatted using a jquery plug in). My code looks like the following. I know the url works fine because if I paste it into my browser, I can see the response, which according to last.fm documentation
The body of the server response
consists of a series of \n (ASCII 10)
terminated lines. A typical successful
server response will be something like
this:
OK
17E61E13454CDD8B68E8D7DEEEDF6170
http://post.audioscrobbler.com:80/np_1.2
http://post2.audioscrobbler.com:80/protocol_1.2
So I know my URL is fine. Now I am wondering how I get at this information, and why my version of their example does not work.
function performHandshake(sk, token, ts){
var token = md5(apiSecret + ts);
var urlToUse = "http://post.audioscrobbler.com/?hs=true&p=1.2.1&c=tst&v=1.0&u=chamals&t=" + ts + "&a=" + token + "&api_key=" + apiKey + "&sk=" + sk + "&format=xml&callback=cbfunc";
$('#container').load(urlToUse);
$.ajax({
url: urlToUse,
type: 'GET',
success: function(res){
var headline = $(res.responseText).find('a.tst').text();
window.console.log(headline);
}
});
}
Well the page you linked you talks about using YQL and jQuery. It's a very interesting solution. However, your example seems to skip over the YQL part (which is crucial).
var urlToUse = "http://post.audioscrobbler.com/?hs=true&p=1.2.1&c=tst&v=1.0&u=chamals&t=" + ts + "&a=" + token + "&api_key=" + apiKey + "&sk=" + sk + "&format=xml&callback=cbfunc";
var yqlUrl2Use = "http://query.yahooapis.com/v1/public/yql?"+
"q=select%20*%20from%20html%20where%20url%3D%22"+
encodeURIComponent(urlToUse)+
"%22&format=xml'&callback=?"
// this function gets the data from the successful
// JSON-P call
Then you'll have to call the call the new URL as a JSONP req...
$.getJSON(yqlUrl2Use, function(json){
// figure out the format of the answer here...
});
Yeah, cross browser scripting. You can't AJAX anything like that since it violates the same domain policy.
You are going to have to setup a proxy on the same server the JavaScript is running from.
Edit Lookslike you need the $('#container').load(url) bit for that to work.
Go back an reread the linked article carefully.
You need to use $.getJSON rather than $.ajax() to return cross site information.
The var res actually has my information that I needed. I guess their headline = part was specifically for their implementation.
Thanks to those who helped!