Page is not displaying JSON object properties - javascript

My code is not playing object properties into the console, however the code displays the object just fine. What am I not able to access the information in this object?
Here is my code:
// APOD
(function Apod() {
var api_key = 'NNKOjkoul8n1CH18TWA9gwngW1s1SmjESPjNoUFo';
var url = 'https://api.nasa.gov/planetary/apod' + "?api_key=" + api_key;
var apodRequest = new XMLHttpRequest();
var apodDATA = "";
apodRequest.onreadystatechange = function() {
apodRequest.onload = function() {
var responseObject = apodRequest.response;
apodDATA = responseObject;
$("document").ready(function() {
$("#apodimage").attr("src", responseObject.hdurl);
});
console.log(responseObject.url);
};
}
apodRequest.open("GET", url, true);
apodRequest.send(null);
}());
Here is the JSON "object" that displays fine on the responseObject variable (properties are giving me undefined):
{
"date": "2016-11-06",
"explanation": "A mere 20,000 light-years from the Sun lies NGC 3603, a resident of the nearby Carina spiral arm of our Milky Way Galaxy. NGC 3603 is well known to astronomers as one of the Milky Way's largest star-forming regions. The central open star cluster contains thousands of stars more massive than our Sun, stars that likely formed only one or two million years ago in a single burst of star formation. In fact, nearby NGC 3603 is thought to contain a convenient example of the massive star clusters that populate much more distant starburst galaxies. Surrounding the cluster are natal clouds of glowing interstellar gas and obscuring dust, sculpted by energetic stellar radiation and winds. Recorded by the Hubble Space Telescope, the image spans about 17 light-years. Follow APOD on: Facebook, Google Plus, Instagram, or Twitter",
"hdurl": "http://apod.nasa.gov/apod/image/1611/ngc3603_hubble_3885.jpg",
"media_type": "image",
"service_version": "v1",
"title": "Starburst Cluster in NGC 3603",
"url": "http://apod.nasa.gov/apod/image/1611/ngc3603_hubble_960.jpg"
}

What you get from the server is probably just a string, not an object.
You can parse the JSON string and convert it to object using JSON.parse.
var obj = JSON.parse(responseObject);
console.log(obj.url);
You can check the type of the variable using typeof. So if you print console.log(typeof responseObject), you'll get "string". If it was an object, you'd get "object".
Also, since you are already using jQuery, consider doing ajax requests by jQuery itself. It would be way more elegant. Read the documentation here.

USE JSON.parse for converting your response to json because your request is returning string
Note:- Do not use $("document").ready() inside ajax response
its working fine for me
(function Apod() {
var api_key = 'NNKOjkoul8n1CH18TWA9gwngW1s1SmjESPjNoUFo';
var url = 'https://api.nasa.gov/planetary/apod' + "?api_key=" + api_key;
var apodRequest = new XMLHttpRequest();
var apodDATA = "";
apodRequest.onreadystatechange = function() {
apodRequest.onload = function() {
var responseObject = apodRequest.response;
apodDATA = responseObject;
$("#apodimage").attr("src", responseObject.hdurl);
var json = JSON.parse(responseObject);
console.log(json.url);
};
}
apodRequest.open("GET", url, true);
apodRequest.send(null);
}());

Related

Can I use two parameter event for one function?

What I want to do is change the url.
Replace the Object word with an event parameter called e1.
Replace the word field with the event parameter e2.
I know this code is not working.
But I don't know how to do it.
The following is my code that I just wrote.
function getAllFieldValue(e1,e2) {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var url = 'test123.my.salesforce.com/services/data/v44.0/queryAll?q=SELECT Field FROM Object';
var url = url.replace('Object',e1);
var url = url.replace('Field',e2);
var response = UrlFetchApp.fetch(url,getUrlFetchOptions());
var json = response.getContentText();
var data = JSON.parse(json);
var fieldValues = data.records;
for(var i=0;i<fieldValues.length;i++){
var fieldValue = fieldValues[i].e;
ss.getRange(i+1,1).setValue(fieldValue);
}
}
I want to take the data from another database through this code and put it in the Google spreadsheet.
For e1, it means the object value selected in the dropbox.
For e2, it means the field of the object selected in the drop box.
Is there a way to use two event parameters for one function?
I look forward to hearing from you.
====================
Please understand that I am using a translator because I am not good at English.
Checking fieldValues[i] in Logger.log returns the following values:
[{
attributes={
type=Account,
url=/services/data/v44.0/sobjects/Account/0015i00000BS03VAAT
},
Name=University of Arizona
},
{
attributes={
type=Account,
url=/services/data/v44.0/sobjects/Account/0015i00000BS03TAAT
},
Name=United Oil & Gas Corp.
},
{
attributes={
type=Account,
url=/services/data/v44.0/sobjects/Account/0015i00000BS03ZAAT
},
Name=sForce
}]
The issues I am currently experiencing are as follows.
If I select 'Name' from the drop-down list, ec2 becomes 'Name'.
As far as I'm concerned,
var fieldName = fieldValues[i].e2 is
var fieldName = fieldValues[i].Name
It means that.
I think fieldValues[i].e2 should return the values of University of Arizona, United Oil & Gas Corp, sForce.
But in reality nothing is returned.
var fieldName = fieldValues[i].Name works properly.
I think there is a problem with fieldValues[i].e2
This is the problem I'm currently experiencing.
There was no problem with the parameters e1, e2, which I thought was a problem. The reason why the code did not work is because of the for loop var fieldValue = fieldValues[i].e; Because it didn't work properly.
var fieldName = fieldValues[i].e2
to
var fieldName = fieldValues[i][e2]
After modifying it like this, the code works properly.

Loop function on Apps Scripts & Google Natural Language API

I am learning how to code so sorry if this is too basic, but I am getting troubles here:
I've been trying to invoke the Google Natural Language API, to give me information about information on 210 rows of my Google Spreadsheet (the whole table has 211 rows). I would like to save the results on 1 Json File.
I am trying to run a loop with the code below, but I am getting the Json file only with the information corresponding to the 1st row. Tried as well to put the "Driveapp.createFile line of code" inside of the loop function, but then I have many Json files, each one with the information corresponding to one row. And what I would like is 1 Json file, with the corresponding information of the 210 rows.
I would appreciate your help, please.
function analyzeText() {
var client = "Spreadsheet_ID";
var query = SpreadsheetApp.openById(client).getSheetByName("1. Template");
var result = SpreadsheetApp.openById(client).getSheetByName("Teste - Natural Language API");
var lrow = query.getLastRow();
for(var i=2; i<=211;i++)
{
var text = query.getRange(i,211).getValue()
var requestUrl = [
'https://language.googleapis.com/v1beta2/documents:analyzeEntities?key=',
'API_KEY_XXXXXXXXXXXXXXXXXXX'
].join("");
var data = {
"document": {
"language": "en-us",
"type": "PLAIN_TEXT",
"content": text
},
"encodingType": "UTF8"
};
var options = {
method : "POST",
contentType: "application/json",
payload : JSON.stringify(data)
};
var response = UrlFetchApp.fetch(requestUrl, options);
var data = JSON.parse(response);
}
DriveApp.createFile('response3.json', response, MimeType.PLAIN_TEXT);
}
I would suggest you instead of the approach you are taking (using a for loop and the method getValue(), which it's a slow method to call in a loop), consider this one I am giving you with this code:
function analyzeText() {
var clientId = "your-sheet-id";
var ss = SpreadsheetApp.openById(clientId);
var templateSheet = ss.getSheetByName("1. Template");
// .getRange(row, column, numRows) -> From the first row and col, take the next 4 rows
// Modify these arguments depending in where you want to start and how many rows you want
var data = templateSheet.getRange(1, 1, 4).getValues();
// You will get an array 2D, using join you will able to get an string from
// all the elements in that array
var text = data.join();
var requestUrl = [
'https://language.googleapis.com/v1beta2/documents:analyzeEntities?key=',
'API_KEY_XXXXXXXXXXXXXXXXXXX'
].join("");
// Now text will have all your cell values and you only need to do one request
var data = {
"document": {
"language": "en-us",
"type": "PLAIN_TEXT",
"content": text
},
"encodingType": "UTF8"
};
var options = {
method : "POST",
contentType: "application/json",
payload : JSON.stringify(data)
};
var response = UrlFetchApp.fetch(requestUrl, options);
var data = JSON.parse(response);
DriveApp.createFile('response3.json', response, MimeType.PLAIN_TEXT);
}
In this way, you only need to make one request and it will be faster than running 211 times your loop. I would also recommend you to check:
Apps Script Quotas: Running your code as you have it, it would give you more chances of hitting these quotas.
Best Practices: You can check more about the best practices so you can have a better idea about why I was telling you to avoid the getValue() method in a loop.

Take an API response object and replace (map) all the keys

I'm adding some APIs to a JavaScript project to replace what used to be multi-field manual data entry with lookups. (E.g., we want to stop asking you 20 questions about a car, and instead just ask your VIN and autopopulate the other 19 answers from a VIN decoder.)
I'm spending more time than I'd like mapping data from the response schema into the existing internal schema of my app. Lots of the work requires a human touch to suss out synonyms, like:
internal.postal_code = api.zipCode;
Some times I find myself writing a really gnarly if to avoid a sometimes-null or missing object half way down a deep tree, like
if(api.a && api.a.b && api.a.b.c){
internal.z = api.a.b.c.d;
}
Is there a good library that would let me write a simple map and do all this work for me? A map might look like:
map = {
'zipCode' : 'postal_code',
'a.b.c.d' : 'z'
};
mapperTool( api, internal, map );
(Note the internal object is stitched together from several APIs and pre-existing tools, so adding or overwriting properties on internal is better than outputting a new object.)
Try this:
function mapperTool(source, desc, map) {
Object.keys(map).forEach(function(key) {
var value = key.split('.').reduce(function(obj, name) {
if (obj && obj[name]) {
return obj[name];
}
}, source);
desc[map[key]] = value;
});
}
var map = {
'zipCode' : 'postal_code',
'a.b.c.d' : 'z'
};
var internal = {};
mapperTool({a:{b:{c:{d: 10}}},zipCode:20}, internal, map);
document.body.innerHTML = '<pre>' + JSON.stringify(internal, true, 4) + '</pre>';

Google Spreadsheet - return values to multiple columns

I'm trying to do something that is beyond my junior coding capabilities. I have created a function that will parse API data into Google Spreadsheet, but no matter what I've tried (and searched online for answers), the results are only being posted to a single column.
The code I am using currently is:
function getAPIdata (URL,key){
var apiurl = "https://example.com/Site/"+URL+"/students?&ID="+key
var rank_data = parse(apiurl)
var result = []
var data_dictionary = rank_data.Student
for (var i in data_dictionary){
result.push(data_dictionary[i].Name)
result.push(data_dictionary[i].Grade)
}
return result
}
The data in question that is being parsed is
Student": [
{
"Name": ​Adam,
"Grade": 75
},
{
"Name": ​Alan,
"Grade": 90
}
What is happening is that when I call the function in excel I am getting a single column with:
Adam
75
Alan
90
What I would like to do is have the following (spaces here delineate another column)
Adam 75
Alan 90
Basically, I have a 1x4 output and I would like a 2x2 output. Is there anyway I could do this? I realize I can call the function twice and push different data sets each time, but in this case I can only call the API once for all data. I thought about potentially pulling the data, caching it but before I delve down learning a path that will not bear fruit, I was hoping some of the experts here could weigh in.
Thanks for reading!
I think you can use [] and push a row at a time, like
function getAPIdata (URL,key){
var apiurl = "https://example.com/Site/"+URL+"/students?&ID="+key
var rank_data = parse(apiurl)
var result = []
var data_dictionary = rank_data.Student
for (var i in data_dictionary){
result.push([data_dictionary[i].Name, data_dictionary[i].Grade])
}
return result
}

Deserializing JSON from local storage to Fabric JS object - JSON created from form data

I'm using Fabric js for a project I'm working on and encountering a few difficulties. My aim is to allow a user to enter details into a form. The form will then be turned into a JSON object and stored using local storage.
Upon pressing submit the user is taken to a new page where the JSON is retrieved and objects are created.
I'm having difficulty with the latter part. Getting the information from the form into JSON is working fine, various tests show that the output is as it should be.
When creating the object there are problems, the object is showing on the canvas as a simple border with corners, it can be moved and selected but all other attributes such as size and colour are lost. I think it's because of how the JSON is being deserilized. I've searched for a solution but yet to find one, any help is hugely appreciated.
Sample code:
This is my test instance that creates an object as expected:
var a = {
type: "rect",
left:200,
top:110,
fill:'red',
width:80,
height:50
};
The same as above but from the local storage:
[Log] From JSON: {"type":"rect","top":"110","left":"200","fill":"red","height":"50","width":"80"} (sim.html, line 135)
To get the data I'm using:
var test = localStorage.getItem("Number1");
console.log("From JSON: " +test);
var obj = JSON && JSON.parse(test) || $.parseJSON(test);
console.log(obj.type +"-"+ obj.left);
When a is added in the below method it works yet obj does not. The main difference I can see if the quotations but I'm not sure if that is the issue and if so how to remove it simply.
Function to iterate over and render objects:
fabric.util.enlivenObjects([circle1, obj], function(objects) {
var origRenderOnAddRemove = canvas.renderOnAddRemove;
canvas.renderOnAddRemove = false;
objects.forEach(function(o) {
canvas.add(o);
});
canvas.renderOnAddRemove = origRenderOnAddRemove;
canvas.renderAll();
});
Many thanks for any help.
I think you can modify your "serialize" routine so that it converts appropriate inputs to numbers:
$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
$.each(a, function() {
var value = this.value || '';
if (/^\d+$/.test(value))
value = +value;
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(value);
} else {
o[this.name] = value;
}
}} );
return o;
};
That looks for input values that look like numbers and converts them. (It only looks for integers; if you wanted to also test for numbers with decimal fractions the regular expression could be modified.)
This isn't the most robust thing in the world, since it's making a fairly big assumption. To be more accurate you'd have to do something like tag your form inputs with a class to identify whether they're supposed to be treated as numeric, and then implement your own serializer to traverse all the inputs.

Categories