How to load data using XHR in D3 - d3.js

I am experimenting with D3 on my localhost. I would like to load data to be visualized from an external source on the Internet.
I am looking for instruction/examples of how to how to load data using XHR in D3 (there is documentation here, but it does not suffice for me, I am looking for code snippets https://github.com/mbostock/d3/wiki/Requests)
I have tried the following and it does not work for me:
d3.xhr("http://example.org/json-test.json", function(data){
alert(data); //no data is returned
});
Thanks

In the latest version of D3, the first argument of the callback is the error, if any, and the second the data. No data in the first argument (which you're checking) suggests that the request was successful. See the documentation for more details.

update to the update:
The d3-request module has been superseded by the d3-fetch module. It handles JSON, CSV, TSV and plain text.
update:
Just in case someone arrives here looking for xhr in d3: this functionality is now supported in the d3-request module.

Your function callback should look like this
v---- missing param
d3.xhr("http://example.org/json-test.json", function(error, data){
// code...
});
That is the typical callback structure in javascript/node.js, error first then data.

Related

Uncaught SyntaxError: Unexpected token <, when calling angularJS $http.jsonp

I'm trying to work with the IUCN Red List web services API (here's an example output). Unfortunately I haven't been able to find any documentation other than this one-off Gist. It looks as though the API is constructing an HTML document rather than returning a data object, which isn't something I've experienced in the past. I also notice that in the example there is no mention of a ?callback=JSON_CALLBACK in the URL, which I would expect when dealing with JSONP.
I've constructed an http request in AngularJS like so:
atRiskApp.controller('IucnController', ['$scope', '$routeParams', '$http', function ($scope, $routeParams, $http) {
$scope.iucn = $routeParams.iucn; // pulling a number from the URL: ex. 22718591
$scope.getIUCN = function () {
var iucnUrl = 'http://api.iucnredlist.org/details/' + $scope.iucn + '/0.js';
$http.jsonp( url )
.success( function (response) {
console.log(response);
})
.error( function (response) {
console.log(response);
});
};
}]);
Although the HTML document is being successfully passed to my app I'm getting the following error message:
Uncaught SyntaxError: Unexpected token <
It seems like the app is expecting to get Javascript, and is instead getting an HTML document, which it apparently can't parse. I've tried adding a config object to the request based on the angular docs: $http.jsonp( {url: iucnUrl, responseType: 'text'} ) without any luck.
My question is, how do I work with the returned HTML document, or am I way off track here?
Response from the API is an HTML document with a javascript extension:
On the page you linked to in your comment , I found some potentially useful information under the heading API Index.
You can actually get JSON for all levels of taxonomy, including your example Aneides aeneus. However, this JSON doesn't include all of the data from the HTML version, so it's not as useful. Hopefully this helps a little.
API Index (excerpt)
It is also possible to retrieve the row(s) of the index corresponding to an individual species:
http://iucn-redlist-api.heroku.com/index/species/panthera-leo.json
You can use dashes for spaces, as a convenient replacement for the standard URL escape, %20.
The HTML format contains direct links to the species account pages. The CSV and JSON formats include a species_id column which can be used to construct species account URLs as follows:
http://iucn-redlist-api.heroku.com/details/species_id/0
To use the index JSON in Web pages directly, you may need JSONP padding; use the “.js” extension and add a “callback” parameter with the name of the function to use.
http://iucn-redlist-api.heroku.com/index/genus/Dioscorea.js?callback=show
I diagonally looked over the website and its sitemap and found no reference to a public API. All the output is HTML, and it makes sense that json parse method jsonp will not be able to make sense of it. First < it encounters, it will fail (as is apparent).
First of all, I would contact the site admin to simply ask if there is an API that will yield you XML or json or some other object notation that's convenient to work with.
Then there's the scenario where his or her answer would be 'no':
Parsing HTML is not something to be taken lightly and certainly not something you would write yourself unless absolutely necessary.
Luckily, there are ways to get data from html using jQuery.parseHTML(), pure ('vanilla') javascript ways you can use from within AngularJS and full-blown HTML parsing libraries such as HTML Agility Pack(for use in .NET), all of which can get you to the heart of the data within the DOM nodes you're trying to poke at.
There are many other libraries that might serve you better, but these examples will give you a good starting point to canvas the landscape of HTML parsing. This will take some looking into, but it will be more than worth it.

reading data from Ruby in D3 (JSON)

i'm confused how to read data from ruby class.
assume i have a class, called "Points".
what i want is reading the all data from this 'Points'.
what i did is like this :
var allPoints = <%= Point.all.to_json %>;
d3.json('allPoints',
function(data){ .......}
i dont know why but somehow d3 can't read the varable allPoints.
is there maybe something i forget to put in code?
or maybe there's another way to read all data from Ruby?
d3.json() is used for performing an AJAX call and retreiving JSON data from a server, which is then passed to the provided callback. It appears that what you're doing is generating a page with your data embedded in the page as a JavaScript. To use this object, just use it. Use whatever code was in your callback function, replacing the name data with allPoints.

JSONP, do you have to change your JSON file?

Can someone help me understand JSONP a little better?
I have a json file being out putted to a url. But due to same-origin policy I need to use JSONP. My question is do I need to change the actual JSON file or will using an ajax call with jquery, dataType: 'jsonp' do the work for me?
JSONP is nothing but, JSON with padding i.e. JSON wrapped by a function call. This format helps to pass the JSON data to java script.
JSON came into picture, when the JSON i.e. java script object can be used to represent the data, which was previously represented in the form of XML.
For example,
var data={...}; is data in json format. Whereas In JSONP, same data is written as getData(data);
In your scenario of ajax call, dataType:'jsonp', json data has to be passed as an argument to a function. You can access the response in that function.
If you could have provided some code, it will be easy to resolve your query. Information about JSONP is available on wikipedia here.
You will have to wrap your JSON data in a function call.
Like, someFunctionName(YOUR_EXISTING_JSON_DATA);
And,
use someFunctionName as jsonp callback
See, Cross-domain communications with JSONP

ajax url for jstree on couchdb (via list function)

I have a CouchDB list function returning the html for the jstree. I am not sure if the url in my HTML form, to invoke the list is correct, since the jstree doesn't render. (with the same html pasted locally, it does). CouchDB is running on localhost.
The location of my list function is standard, "appname/app/lists/myList.js". I have tried several combinations of url, on the lines of "/appname/_design/appname/_list/listname/viewname".
What should be the correct form ?
Thanks.
The format should be as follows:
GET /db/_design/design-doc/_list/list-name/view-name
I copied this directly from the CouchOne Documentation.
OK, since I couldn't find a definite answer for rendering jstree with dynamic data using a CouchDB list, I went the other way and used after.js functionality in evently.
This is for anyone who might find it useful. This is what worked for me,
get the data using data.js
render it as <ul><li/></ul> in mustache.html
in after.js write the function for jstree as shown in the jstree documentation for html_data plugin
(after.js looks like this
function (e) {
$('.mytree').jstree({
"plugins" : [ "themes", "html_data", "checkbox" ]
});
}

jQuery AJAX Form, cannot send array?

I'm practicing my jQuery skills (ok, learning too) and experienced an issue. I got a file upload form with file input. I'm using this plugin (http://www.fyneworks.com/jquery/multiple-file-upload/#tab-Uploading) to upload multiple files at once. So I'm using following form input:
<input type="file" class="multi" name="photo[]" accept="gif|jpg|jpeg|png" maxlength="5"/>
Now... I'm trying to send an AJAX request to php file that will handle upload and server-side validation:
$('#upload_photos_s').click(function(q){
var photo = $('[name=photo[]]').val();
// Process form
$.ajax({
type: "POST",
url: "upload.php",
data: 'photo[]='+photo,
success: function(html){
alert($('[name=photo[]]').val());
$("#photo_upload_form").html(html);
}
});
return false;
});
While using Firebug I can see that there's only one file in photo[].
Any suggestions why? Is there something I missed?
Regards,
Tom
As it stands, you are indeed querying the value of the first photo[] member only. photo[].val() will not return an array containing all the values.
You would have to run through each member of photo[], e.g. using each(), to build an array of values.
However, I'm not sure this is the right path to go for whatever you want to do. You are aware that what you are doing is uploading the file names only, not their data?
It is not possible to upload files using AJAX without the help of additional tools like Flash-based SWFUPload. This is for security purposes to prevent scripts from having direct access to local files.
Maybe what you're trying to do is best suited for an approach where the form's target property points at an <iframe>. That would not trigger a reload of the page, but still submit the form the "traditional" way, allowing for old-school file uploads.
Well on the link you provided, there is a part called Ajax specifying the simplest way is to use the jQuery Form Plugin.
Documentation of plugins help a lot usually ^^.
Have a nice day :)

Resources