myObj.forEach(), isn't working - javascript

I'm trying store a XMLHttpRequest()'s results as a JSon String in an object, The data in the String is several arrays. I'm trying to then read through each array, in myObj.
Obviously, myObj.forEach() doesn't work, because myObj is an object, not an array or a list. How do I make it so I can itterate through myObj, and then use a forEach on each array?
Here is my current code
function getFile(){
var input = document.getElementsByName("json")[0];
var filename = input.value;
console.log(filename);
var xhr = new XMLHttpRequest();
xhr.open("GET", filename, true);
xhr.send(null);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var text = xhr.responseText;
document.getElementById("displayText").innerHTML = "";
var myObj = JSON.parse(text);
myObj.forEach(function(student) {...});
}
}
}

You can grab the keys of the Object into a list using Object.keys() and then iterate through them assuming they are all lists:
function getFile(){
var input = document.getElementsByName("json")[0];
var filename = input.value;
console.log(filename);
var xhr = new XMLHttpRequest();
xhr.open("GET", filename, true);
xhr.send(null);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var text = xhr.responseText;
document.getElementById("displayText").innerHTML = "";
var myObj = JSON.parse(text);
var keys = Object.keys(myObj);
keys.forEach(function(key) {
myObj[key].forEach(function(item) {...})
});
}
}
}

Related

How to get data from a local JSON file in Javascript

I'm trying to retrieve a specific ID from the JSON file depending on user input and then display a picture based on the ID retrieved from the JSON file
function showCard() {
var cardNaqme = document.getElementById('un').value;
var cardNameProper = cardName.replace(/\s/g, '');
var obj = JSON.parse("https://db.ygoprodeck.com/api/v7/cardinfo.php"+cardNameProper)
var imgId = obj["data"][0]["id"]
document.getElementById("chosenCard").src = "https://storage.googleapis.com/ygoprodeck.com/pics_small/"+imgId+".jgp";
event.preventDefault();
}
I think what you need is below but I am not sure I understood your json structure:
var cardNaqme = document.getElementById('un').value;
var cardNameProper = cardName.replace(/\s/g, '');
var oReq = new XMLHttpRequest();
oReq.open("GET", "https://db.ygoprodeck.com/api/v7/cardinfo.php"+cardNameProper", true);
oReq.responseType = "json";
oReq.onload = function(e) {
JSONObject json = new JSONObject(res);
JSONArray ja = json.getJSONArray("data");
JSONObject obj = ja.getJSONObject(0);
var imgId = obj.id;
document.getElementById("chosenCard").src = "https://storage.googleapis.com/ygoprodeck.com/pics_small/"+imgId+".jgp";
}
oReq.send();
I tried to answer your problem after identifying your problem.
function showCard()
{
event.preventDefault();
var cardNaqme = document.getElementById('un').value;
var cardNameProper = cardName.replace(/\s/g, '');
var obj = JSON.parse("https://db.ygoprodeck.com/api/v7/cardinfo.php"+cardNameProper)
var imgId = obj[0].id
document.getElementById("chosenCard").src =
"https://storage.googleapis.com/ygoprodeck.com/pics_small/"+imgId+".jpg";
}

How to make a variable from json using XMLHttpRequest?

I would like to get an array with objects from json using XMLHttpRequest() and assign it to a variable.
If i log it in a console it shows the array.
function getData() {
let myJson = [];
var xhr = new XMLHttpRequest();
var url = 'https://www.reddit.com/r/funny.json';
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var jsonData = JSON.parse(xhr.responseText);
arr = jsonData.data.children;
for (let i = 0; i < arr.length; i++) {
let newObject = {};
newObject.title = arr[i].data.title;
newObject.upvotes = arr[i].data.ups;
newObject.score = arr[i].data.score;
newObject.num_comments = arr[i].data.num_comments;
newObject.created = arr[i].created_utc;
myJson.push(newObject);
}
}
};
xhr.open("GET", url, true);
xhr.send();
return myJson;
}
let data = getData();
console.log(data[0]);
But if I try to do anything with (console.log(data[0]);) it it returns undefined. What am I doing wrong? Thanks for any explanation! Cheers.
Just pass in the callback function instead of returning the value from an asynchronous XML HTTP request.
function getData(callback) {
var xhr = new XMLHttpRequest();
var url = 'https://www.reddit.com/r/funny.json';
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var jsonData = JSON.parse(xhr.responseText);
arr = jsonData.data.children;
let myJson = [];
for (let i = 0; i < arr.length; i++) {
let newObject = {};
newObject.title = arr[i].data.title;
newObject.upvotes = arr[i].data.ups;
newObject.score = arr[i].data.score;
newObject.num_comments = arr[i].data.num_comments;
newObject.created = arr[i].created_utc;
myJson.push(newObject);
}
// Invoke the callback now with your recieved JSON object
callback(myJson);
}
};
xhr.open("GET", url, true);
xhr.send();
}
getData(console.log);
Your return happens outside of the onreadystatechange. So you exit before you even have the data.
Pass in a callback function to call when you have the data, or have the asynchronous call return a JS Promise that resolves with the gotten data.

Protractor - How do I pass a string value from a previous function to an async script?

The issue I'm having is that I have a dynamic API call whose url changes everytime. So In order to get the proper URL I have to get the text on the page and parse it so it only the first part of the text, then concatenate that to the first part of the URL. When I try to pass the string to the async script it keeps coming up as undefined. How can I get the string into the async script?
Specifically get the string to this line of code:
xhr.open("GET", APIcall, true);
var ID = element(by.css(".sometext")).getText().then(function(getFirstPartOfText) {
//console.log(ID);
var thing = getFirstPartOfText
var thing2 = getFirstPartOfText.toString().split(" ");
var thing3 = thing2[0];
var API = "https://someAPIcall/read/";
APIcall = API + thing3;
return APIcall;
}).then(function(APIcall){
console.log(APIcall);
browser.executeAsyncScript(function(ApiCall) {
var callback = arguments[arguments.length - 1];
var xhr = new XMLHttpRequest();
xhr.open("GET", APIcall, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
callback(xhr.responseText);
}
};
xhr.send('');
}).then(function(str) {
console.log(str);
//var whatINeed = JSON.parse(str);
var ID = element(by.css(".sometext")).getText().then(function(getFirstPartOfText) {
// this is synchronous, so there's no need to chain it using .then()
var thing = getFirstPartOfText
var thing2 = getFirstPartOfText.toString().split(" ");
var thing3 = thing2[0];
var API = "https://someAPIcall/read/";
APIcall = API + thing3;
return APIcall;
});
call_something(ID); // ID should be set at this point.
function call_something (APIcall) {
console.log(APIcall);
browser.executeAsyncScript(function(ApiCall) {
var callback = arguments[arguments.length - 1];
var xhr = new XMLHttpRequest();
xhr.open("GET", APIcall, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
callback(xhr.responseText);
}
};
xhr.send('');
}).then(function(str) {
console.log(str);
}
}
There are multiple things going on here, first of all the callback in call_something is not required, you are still within webdriver's promise manager. So all you need to do is return the data for the next call chain. Also quote in xhr.send(''); inside the method are not required. All you need to do is call send() and JSON parse the response and return, the next then block should have the JSON result. If you are getting pure HTML, then make sure the URL is correct.
function call_something (APIcall) {
console.log(APIcall);
browser.executeAsyncScript(function(ApiCall) {
var xhr = new XMLHttpRequest();
xhr.open("GET", APIcall, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
return JSON.parse(xhr.responseText);
}
};
xhr.send();
}).then(function(str) {
console.log(str);
}
}
I was missing an extra parameter mentioned here
The first argument is a function which will be called
The second+ arguments will be passed as arguments to the function in the first argument.
var ID = element(by.css(".sometext")).getText().then(function(getFirstPartOfText) {
//console.log(ID);
var thing = getFirstPartOfText
var thing2 = getFirstPartOfText.toString().split(" ");
var thing3 = thing2[0];
var API = "https://someAPIcall/read/";
APIcall = API + thing3;
return APIcall;
}).then(function(APIcall){
console.log(APIcall);
browser.executeAsyncScript(function(ApiCall) {
var callback = arguments[arguments.length - 1];
var xhr = new XMLHttpRequest();
xhr.open("GET", APIcall, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
callback(xhr.responseText);
}
};
xhr.send('');
}, APIcall).then(function(str) {
console.log(str);
//var whatINeed = JSON.parse(str);

How should I loop through this JSON data?

Here is my code I want to print out "song" property from data. Link to JSON is -> http://starlord.hackerearth.com/sureify/cokestudio
<script type="text/javascript">
var requestURL = 'http://starlord.hackerearth.com/sureify/cokestudio';
var request = new XMLHttpRequest();
request.open('GET', requestURL);
request.responseType = 'json';
request.send();
request.onload = function(){
var myjsondata = request.response;
showdata(myjsondata);
}
function showdata(data){
var song_name = data;
for (i = 0; i < 3; i++) {
document.write(song_name);
document.write("<br>");
}
}
</script>
When I run it in browser I get [object Object],[object Object],[object Object],[object Object],[object Object] as OUTPUT or undefined.
Your data looks like this:
[ //the array in data
{ //the first object, e. g. data[0]
"song":"Afreen Afreen", // song => data[0].song
"url":"http://hck.re/Rh8KTk",
"artists":"Rahat Fateh Ali Khan, Momina Mustehsan",
"cover_image":"http://hck.re/kWWxUI"
},
{
"song":"Aik Alif",
"url":"http://hck.re/ZeSJFd",
"artists":"Saieen Zahoor, Noori",
"cover_image":"http://hck.re/3Cm0IX"
},
{
"song":"Tajdar e haram",
"url":"http://hck.re/wxlUcX",
"artists":"Atif Aslam",
"cover_image":"http://hck.re/5dh4D5"
}]
So to loop over one can do
var limit=Math.max(data.length,100);//max displayed number
for(var i=0;i<limit;i++){
document.write(data[i].song+"<br>");
}
Whole code:
document.write("loading...");
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
var data= JSON.parse(xhr.responseText);
var limit=Math.max(data.length,100);
for(var i=0;i<limit;i++){
document.write(data[i].song+"<br>");
}
}
};
xhr.open('GET', 'http://starlord.hackerearth.com/sureify/cokestudio', true);
xhr.send(null);
You cannot write the whole song object to the document. You should map it first:
var songNames = data.map(function(item) { return item.song; });
This will give you an array of all the names (strings), which you can write to the document:
songNames.forEach(function(songName) {
document.write(songName + '<br>');
});
You need to use JSON.stringify; and if you plan to write to document I suggest wrapping in pre tags as well to retain string format.
let data = [
{
"song":"Afreen Afreen",
"url":"http://hck.re/Rh8KTk",
"artists":"Rahat Fateh Ali Khan, Momina Mustehsan",
"cover_image":"http://hck.re/kWWxUI"
},
{
"song":"Aik Alif",
"url":"http://hck.re/ZeSJFd",
"artists":"Saieen Zahoor, Noori",
"cover_image":"http://hck.re/3Cm0IX"
},
{
"song":"Tajdar e haram",
"url":"http://hck.re/wxlUcX",
"artists":"Atif Aslam",
"cover_image":"http://hck.re/5dh4D5"
}
];
document.write('<pre>'+ JSON.stringify(data, null, '\t') + '</pre>');
You need to stringify the object to make it readable.
<html>
<body>
<script type="text/javascript">
var requestURL = 'http://starlord.hackerearth.com/sureify/cokestudio';
var request = new XMLHttpRequest();
request.open('GET', requestURL);
request.responseType = 'json';
request.send();
request.onload = function(){
var myjsondata = request.response;
showdata(myjsondata);
}
function showdata(data){
var song_name = data;
for (i = 0; i < 3; i++) {
document.write(JSON.stringify(song_name));
document.write("<br>");
}
}
</script>
</body>
</html>
The response from the request is an array of json objects and you are just trying to write the return object over and over again. You need to iterate over the returned data and output each object's value. Change your showdata function as:
function showdata(data){
for (i = 0; i < 3; i++) {
document.write(data[i].song);
document.write("<br>");
}
}

JS search returned xhr.responseText for div then remove div

I would like to search a xhr.responseText for a div with an id like "something" and then remove all the content from the xhr.responseText contained within that div.
Here is my xhr code:
function getSource(source) {
var url = source[0];
var date = source[1];
/****DEALS WITH CORS****/
var cors_api_host = 'cors-anywhere.herokuapp.com';
var cors_api_url = 'https://' + cors_api_host + '/';
var slice = [].slice;
var origin = self.location.protocol + '//' + self.location.host;
var open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function () {
var args = slice.call(arguments);
var targetOrigin = /^https?:\/\/([^\/]+)/i.exec(args[1]);
if (targetOrigin && targetOrigin[0].toLowerCase() !== origin &&
targetOrigin[1] !== cors_api_host) {
args[1] = cors_api_url + args[1];
}
return open.apply(this, args);
};
/****END DEALS WITH CORS****/
var xhr = new XMLHttpRequest();
xhr.open("GET", cors_api_url+url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var resp = xhr.responseText;
var respWithoutDiv = removeErroneousData(resp);
}
else{
return "Failed to remove data.";
}
}
xhr.send();
}
remove div here:
/*This must be in JS not JQUERY, its in a web worker*/
function removeErroneousData(resp) {
var removedDivResp = "";
/*pseudo code for removing div*/
if (resp.contains(div with id disclosures){
removedDivResp = resp.removeData(div, 'disclosures');
}
return removedDivResp;
}
You can dump the response in a div and then search for that div you want empty its content.
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var resp = xhr.responseText;
$('div').attr('id', 'resp').html(resp);
$('#resp').find('disclosures').html('');
//var respWithoutDiv = removeErroneousData(resp);
}
else{
return "Failed to remove data.";
}
}

Categories