I am looking to parse the following page and extract every instance of a name. http://api.openparliament.ca/politicians/.
I have been following this guide for reference: https://www.taniarascia.com/how-to-connect-to-an-api-with-javascript/ However when it runs, there is nothing returned. What am I doing wrong?
var request = new XMLHttpRequest();
request.open('GET', 'api.openparliament.ca/politicians/?format=json', true);
request.onload = function () {
// Begin accessing JSON data here
var data = JSON.parse(this.response);
if (request.status >= 200 && request.status < 400) {
data.forEach(politicians => {
console.log(politicians.name);
});
} else {
console.log('error');
}
}
request.send();
Welcome Sean to StackOverflow.
Well, first of all you have some issues in your code.
Add the http:// in the URL in this line: request.open('GET', 'http://api.openparliament.ca/politicians/?format=json', true);.
You need to wait for XMLHttpRequest.readyState is DONE. In your code you can check the readyState property in this way:
if (request.readyState === 4) {
// Code goes here...
}
Check if the XMLHttpRequest has returned a 200 status code. You can do in this way:
if (request.status === 200) {
// Code goes here...
}
Then with the previous code you can do:
var data = JSON.parse(this.response);
Where data is an object that it has two properties: objects and pagination where objects is an array of objects and pagination is an object.
Then you can do:
data.objects.forEach(politician => {
console.log(politician.name);
});
Here is the complete demo:
(function() {
var request = new XMLHttpRequest();
request.open('GET', 'http://api.openparliament.ca/politicians/?format=json', true);
request.onreadystatechange = function() {
if (request.readyState === 4) {
if (request.status === 200) {
var data = JSON.parse(this.response);
data.objects.forEach(politician => {
console.log(politician.name);
});
} else {
console.log('error');
}
}
}
request.send();
}());
Hope this helps.
Related
I have a one variable file like this.
var geography = [
{ id:"Country", header:"", width:150},
{ id:"Capital", header:"Capital", width:150},
{ id:"Falg", header:"Falg", width:150},
{ id:"Language", header:"Language", width:150},
{id:"Population", header:"Population", width:150},
],
Now I wanted to load this data from the json. I placed this data into JSON file and Using this code.
getGeography function(){
var geography;
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "data.json",true);
}
Now from here how to store into a variable and return that.
It should be read when the ready state of xmlhttp is 4 and response status is 200. You should parse the response with JSON.parse(). However you can't return the value from the function. Because XMLHTTPRequest is asynchronous by default.
function getGeography() {
var geography;
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "data.json",true);
xmlhttp.onreadystatechange = function () {
if(xmlhttp.readyState === 4 && xmlhttp.status === 200) {
geography = JSON.parse(xmlhttp.responseText;)
}
}
}
Instead of returning geography you have to programmatically read the value of geography when the AJAX request is complete. Something like this (read this):
Instead of writing code like this:
function anotherFunc() {
var geography = getGeography();
thenDoSomething(geography);
}
Write like this:
function anotherFunc() {
getGeography();
}
function getGeography() {
var geography;
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "data.json",true);
xmlhttp.onreadystatechange = function () {
if(xmlhttp.readyState === 4 && xmlhttp.status === 200) {
geography = JSON.parse(xmlhttp.responseText);
thenDoSomething(geography);
}
}
}
It's like handing over the control of execution of rest of the code to getGeography() function, instead of expecting a return value from the function and then using that value. The getGeography() function resumes execution of rest of the code with the value received from AJAX response, when the AJAX call completes.
I'm not a fan of jQuery but in this case, you would probably benefit from this.
$.get( "ajax/test.html", function( data ) {
// data is your result
console.log(data);
console.log(JSON.parse(data));
});
https://api.jquery.com/jquery.get/
Here is how to use XMLHttRequest() :
<script>
const req = new XMLHttpRequest();
var geography = [];
req.onreadystatechange = function(event) {
// XMLHttpRequest.DONE === 4
if (this.readyState === XMLHttpRequest.DONE) {
if (this.status === 200) {
geography = JSON.parse(this.responseText);
console.log(geography);
alert("Great Success : check console !");
} else {
alert("Something has gone really Bad !");
}
}
};
req.open('GET', 'data.json', true);
req.send(null);
Be careful to use correct JSON :
[
{"id":"Country","header":"","width":150},
{ "id":"Capital","header":"Capital", "width":150},
{ "id":"Falg","header":"Falg","width":150},
{ "id":"Language","header":"Language", "width":150},
{ "id":"Population", "header":"Population", "width":150}
]
Firstly, I want to confirm that this question is not duplicated with other similar questions on stackoverflow, because my question is only based on javascript, NO jquery.
I wrote website https://www.emojionline.org. Because this site is small, I don't want to use JQuery. I tried to test with Jquery to solve this problem is ok, but I only want javascript without jquery.
My question is problem that return value from ajax callback function. I wrote as follows:
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'emoji.json', true);
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
callback(xobj.responseText);
}
};
xobj.send(null);
}
function returnJSON(){
var jn = '';
loadJSON(function(response){
jn = JSON.parse(response);
});
return jn;
}
var json = returnJSON();
However, the json is null when I use console.log to write? What is this problem? Please help me solve it!
Synchronous request example:
function loadJSON(url) {
var request = new XMLHttpRequest();
request.overrideMimeType("application/json");
request.open('GET', url, false);
request.send();
if (request.readyState === 4 && request.status === 200)
return request.responseText;
}
// An example using ipify api (An IP Address API)
var json = loadJSON('https://api.ipify.org?format=json');
console.log(json);
Or asynchronous request example, using the Promise API and error event handler:
function loadJSON(url) {
return new Promise(function (resolve, reject) {
var request = new XMLHttpRequest();
request.overrideMimeType("application/json");
request.open('GET', url, true);
request.onreadystatechange = function () {
if (this.readyState === 4) {
if (this.status === 200) {
resolve({status: this.status, body: JSON.parse(this.responseText)});
} else {
reject({status: this.status, body: this.responseText});
}
}
};
request.send();
});
}
// An example using ipify api (An IP Address API)
loadJSON('https://api.ipify.org?format=json')
.then(function (response) {
console.log(response);
})
.catch(function (errorResponse) {
console.log(errorResponse);
});
xobj.open(method, url, async, user, password);
xobj.send(null);
reference: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open
I have the following method to log into my API:
login()
{
var formData = new FormData();
formData.append("admin[email]", "user");
formData.append("admin[password]", "pass");
var request = new XMLHttpRequest();
request.open("POST", "my_link");
request.onreadystatechange = (function() {
if (request.readyState === XMLHttpRequest.DONE && request.status === 201)
{
return function() { this.loadMembers(); }
}
});
request.send(formData);
}
Then I have my method that I'm trying to call AFTER my post async request is completely done:
loadMembers()
{
....
}
Now for some reason, this.loadMembers() is never being called. If I put a testing console.log() right above it (not within the return callback) it calls just fine - so I know that the requestState and request status is correct.
Is there a better way to do this? Or what am I doing wrong?
Thanks
It is because you are returning a function instead of just calling loadMembers.
So instead of:
request.onreadystatechange = (function() {
if (request.readyState === XMLHttpRequest.DONE && request.status === 201)
{
return function() { this.loadMembers(); }
}
});
You likely want:
var that = this;
request.onreadystatechange = (function() {
if (request.readyState === XMLHttpRequest.DONE && request.status === 201)
{
that.loadMembers();
}
});
Remember the "this" in login() is not the same this as the one inside the (function() { if....}) so you need to save this var that = this in the way that rasmeister shows.
Following is the way I know for adding parameters to request handlers for XMLHttpRequest.
var request = new XMLHttpRequest();
function ABC() {
if (request) {
request.open('GET', url, true);
request.onreadystatechange = function() { handler(param1, param2); };
request.send();
}
}
function handler(param1, param2) {
if (request.readyState == 4) {
if (request.status == 200) {
//do something on success
} else {
alert("Invocation Errors Occured");
}
}
}
That is fine and good. But, kindly look at the following code.
var request = new XMLHttpRequest();
function ABC() {
if (request) {
request.open('GET', url, true);
request.onreadystatechange = handler;
request.send();
}
}
function handler(evtXHR) {
if (request.readyState == 4) {
if (request.status == 200) {
//do something on success
} else {
alert("Invocation Errors Occured");
}
}
}
Here, i'm calling the handler without any parameter, but i'm getting an object of type XMLHttpRequestProgressEvent in the evtXHR parameter of the code.
Now I have two questions.
How am I getting evtXHR parameter when I make a parameter-less call?
How to add a parameter along with evtXHR so that I still get the XMLHttpRequestProgressEvent object?
So, I want something like this:
function handler(evtXHR, myParam) {
if (request.readyState == 4) {
if (request.status == 200) {
//do something on success
} else {
alert("Invocation Errors Occured");
}
}
}
You aren't making a call. the XHR object is. The handler function is being called by the XHR object in response to receiving the event.
Don't try to pass it as an argument. Use a closure instead.
Such:
var myData = 1234;
request.onreadystatechange = handler;
function handler(event) {
alert(myData); // Use myData from the wider scope instead of trying to pass it as an argument
}
I am doing an XMLHttpRequest and I would like to fallback on doing something else (reading a local file) if it fails, but I want to do it outside of the XHR function (getDBfileXHR) itself.
I am using Jquery too.
How is that possible, given the fact that it doesn't seem to work with .done() and .fail(), maybe with a deferred variable or something else ?
getDBfileXHR( encode_utf8("http://john:hispasswd#mysite.com/DBfile.jsonp") );
//here I want to do something else if getDBfileXHR fails like this :
fallbackToLocalDBfile();
function getDBfileXHR(url) {
var request = new XMLHttpRequest();
request.open("GET", url, true); //3rd parameter is sync/async
request.onreadystatechange = function() { //Call a function when the state changes.
if (request.readyState == 4) {
if (request.status == 200 || request.status == 0) {
console.log('we get a response from XHR');
var jsonText = request.responseText.replace("callback(", "");
jsonText = jsonText.replace(");", "");
storeJsonInProdata(JSON.parse(jsonText));
dbReadyDeferred.resolve();
} else {
console.log('error : request.status = '+request.status);
}
}
}
console.log("Sending XMLHttpRequest...");
request.send();
}
function fallbackToLocalDBfile(){
$.get('proDB.jsonp').done(function(data){
console.log(data);
//storeJsonInProdata(data);
//dbReadyDeferred.resolve();
});
}
Mmm something like this maybe :
var d=$.Deferred()
function getDBfileXHR(url) {
....
if (request.readyState == 4) {
...
d.resolve(_MyData);
} else {
console.log('error : request.status = '+request.status);
d.reject(_myError);
}
}
}
console.log("Sending XMLHttpRequest...");
request.send();
}
d.done(function (a){...}).fail(function (b){});