How do I make multiple API calls via XMLHttpRequest? - javascript

I'm not that experienced when it comes to APIs so excuse me in advance.
I'm trying to get a button to display the contents (response) of an API, and the code below works wonders. I'm wondering how I would make the exact same request, but instead of the "explicit" endpoint, I want a "history" endpoint instead.
How would I do this?
const data = null;
const xhr = new XMLHttpRequest();
xhr.withCredentials = true;
var object1;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
object1 = JSON.parse(this.responseText);
}
document.getElementById('thejoke').innerHTML = object1.value;
});
xhr.open("GET", "https://api.chucknorris.io/jokes/random?category=explicit");
xhr.send(data);

The simplest answer would be to make it a function:
function send(category) {
const url = "https://api.chucknorris.io/jokes/random?category=" + category
const data = null;
const xhr = new XMLHttpRequest();
xhr.withCredentials = true;
var object1;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
object1 = JSON.parse(this.responseText);
}
document.getElementById('thejoke').innerHTML = object1.value;
});
xhr.open("GET", "");
xhr.send(data);
}
And then you can you call it like this:
send("explicit");
The only problem you then face is that object1 is not available outside of the function. You could work around this by making object1 a global variable, or do the things you want to directly in the EventListener.

Related

XMLHttpRequest return from a function before response is back

I have a function as the code below, I am trying to send a file through XMLHttpRequest to the server and then store it in DB and retrieve the id of the file in DB and make an object of ids.
The problem is that the function exits a lot before I got the response back from the server to store it in the object therefore the object doesn't store those values.
I know that I need make the XHR asynchronous but it doesn't change the result, I have also tried timeout or using a different platform like Ajax but still, it didn't work.
async function getFileObj() {
var FileObject = {}
for (let key1 in PObj) {
FileObject[key1] = {}
for (let key2 in PObj[key1]) {
FileObject[key1][key2] = {}
for (let key3 in PObj[key1][key2]) {
const formData = new FormData();
formData.append('myFile.png', filesObjDB[key1][key2][key3]);
var xhr = new XMLHttpRequest();
xhr.open("POST", 'url', true);
xhr.onreadystatechange = async function() {
if (this.readyState === XMLHttpRequest.DONE && this.status === 200)
var id = await xhr.response.text();
FileObject[key1][key2][key3] = parseInt(id)
}
xhr.responseType = 'blob';
xhr.send(formData);
}
}
}
return FileObject;
}
Help would be very appreciated!
You are not awaiting the request. To make the existing code wait for the result, you'd need to wrap the outdated callback-based code in a promise and await that (and also I don't think getting the response text of an XHR works as you showed, I changed it now):
// This is just to demonstrate what was immediately wrong
// with the existing code - it's not the best solution! See below.
FileObject[key1][key2][key3] = await new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.onreadystatechange = function() {
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
var id = xhr.responseText;
resolve(parseInt(id));
}
};
xhr.send(formData);
});
Note there is no error handling yet, if the request fails everything will just hang.
But at that point, it doesn't actually make sense to use XHR in the first place! It's a lot more straightforward to use fetch, which has a promise API out of the box:
const response = await fetch(url, { method: 'POST', body: formData })
FileObject[key1][key2][key3] = parseInt(await response.text())

How to get html source of page, after all it scripts was called?

I'am trying to parse site. The site (i suppose) using scripts and data bases to load data from (dynamically?). And this is my problem... I am trying to grab data through C# (unfortunately i don't have access to code right now) or JS. And it seems like either C# and JS, get only template of the site, but don't wait until all scripts executed. So this is my question, is there any way to get ALL html source? Maybe call scripts somehow. Or make a request, wait for 10 seconds, and then write source html data into variable?
Here is my JS code.
function request(link)
{
var xhr = new XMLHttpRequest();
xhr.open('GET', link, true);
xhr.onreadystatechange = function() .
{console.log(xhr.readyState);};
xhr.send();
let data = xhr.responseText;
var tempDiv = document.createElement('div');
tempDiv.innerHTML = data.replace(/<script(.|\s)*?\/script>/g,
'');
return tempDiv;
}
function loadFile(url, timeout, callback)
{
var args = Array.prototype.slice.call(arguments, 3);
var xhr = new XMLHttpRequest();
xhr.ontimeout = function () {
console.error("The request for " + url + " timed out.");
};
xhr.onload = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
callback.apply(xhr, args);
} else {
console.error(xhr.statusText);
}
}
};
xhr.open("GET", url, true);
xhr.timeout = timeout;
xhr.send(null);
let data = xhr.responseText;
return data;
}
function showMessage (message) {
console.log(message + this.responseText);
}
function include(scriptUrl)
{
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", scriptUrl);
xmlhttp.onreadystatechange = function()
{
if ((xmlhttp.status == 200) && (xmlhttp.readyState == 4))
{
eval(xmlhttp.responseText);
}
};
xmlhttp.send();
let data = JSON.parse(xmlhttp.responseText);
var tempDiv = document.createElement('div');
tempDiv.innerHTML = data.replace(/<script(.|\s)*?\/script>/g,
'');
return tempDiv;
}
All this functions do not work as i want.
This isn't really practical - you're trying to load an HTML page, all associated scripts, then run them on the HTML page as if they were in a proper browser environment, but within your current browser session.
This sort of thing is feasible with the jsdom library if you were running on the server-side (NodeJS), because it simulates browser behaviour: https://github.com/jsdom/jsdom. So you could do
JSDOM.fromURL("https://example.com/", { runScripts: "dangerously" }).then(dom => {
console.log(dom.serialize()); //turn the page back into HTML
});
...to get the whole thing.

Reading JSON data from a url using javascript

I want to read data from this link http://starlord.hackerearth.com/gamesext.
I went through this https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON and was able to obtain data from https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json.
Trying similar approach for getting data from http://starlord.hackerearth.com/gamesext is not working for me.
This is how I tried:
var requestURL = 'http://starlord.hackerearth.com/gamesext';
var request = new XMLHttpRequest();
request.open('GET', requestURL);
request.responseType = 'json';
request.send();
request.onload = function() {
var games = request.response;
document.getElementById("para").innerHTML = "for check";//para is a paragraph id
fun1(games);
}
function fun1(jsonObj){
//getting first title
document.getElementById("para").innerHTML = jsonObj[0]["title"];
}
I would want to know is that data in JSON and how to get it?
Try using the JSON.parse() method:
function fun1(jsonObj){
//getting first title
jsonObj = JSON.parse(jsonObj);
document.getElementById("para").innerHTML = jsonObj[0]["title"];
}
This will turn valid JSON into a javascript object that can be accessed as you are trying to do below.
This works perfectly fine for me:
var requestURL = 'http://starlord.hackerearth.com/gamesext';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(xhttp.response[0].title) # LittleBigPlanet PS Vita
}
};
xhttp.open("GET", requestURL);
xhttp.responseType = 'json';
xhttp.send();
Give it a try!
Using fetch this is pretty simply.
Below is an example.
const url = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
async function getData() {
const json = await (await fetch(url)).json();
console.log(json);
}
getData();
just put request.send(); after all the code you provided.

Passing extra arguments to XMLHttpRequest.onload

I'm trying to comunicate with a server, using XMLHttpRequest in javascript.
How can I pass info to the onload function?
// global variable that containts server response
var reply;
var makeRequest = function(extraInfo) {
var request = new XMLHttpRequest();
request.open(...);
request.onload = handler;
};
var handler = function(data) {
reply = data.target.response;
console.log("Server Reply: " + reply);
};
How can I pass the parameter extraInfo from makeRequest to the handler function? (without using a global variable)
Just use a closure in such way:
...
var makeRequest = function(extraInfo) {
var request = new XMLHttpRequest();
request.open(...);
request.onload = function(data) {
// extraInfo is accessible here
reply = data.target.response;
console.log("Server Reply: " + reply);
};
};
I figured out that passing extra info into the request handler can be done this way: (At least is good for me)
request.open(...);
request.extraInfo = identifier;
request.onload = function() {
identifier = this.extraInfo;
};
The accepted solution didn't work for me, but this did
const params = new FormData();
params.append('selectedValue', selectedValue);
const xhr = new XMLHttpRequest();
xhr.open('post', url, true);
xhr.send(params);
xhr.extraInfo = extraInfo; // <- set your data here
xhr.onload = (e) => {
const data = JSON.parse(xhr.responseText);
alert(xhr.extraInfo) /// <- access it like this
alert(e.target.extraInfo) // <- or like this
//return data;
};

Ionic controller XMLHttpRequest function doesn't work

does somebody know why this doesn't work? I get a error message at 'request.status' in Ionic
.factory('Nieuws', function() {
var url = "http://echo.jsontest.com/ID/2/bericht/test";
var request = new XMLHttpRequest();
request.open("GET", url);
var nieuws;
request.onload = function () {
if (request.status = 200) {
nieuws = JSON.parse(request.responseText);
//console.log(nieuws);
}
};
You're trying to assign a value to a read only property when you need to be making a comparison.
Replace = with ==.

Categories