Create drop down menu from external JSON in Javascript - arrays

I am using an external JSON to retrieve the name of the volcano and put all names into a drop down menu to be selected and shown on my map. Currently, I have no errors on my webpage console but I am not getting any names inside the dropdown. I am very new to coding and I am blank on what is wrong. Any advice?
'''
//Call JSON for map latitude and longitude, showing volcaones locations
// with last eruption in a hover feature
var data = {};
d3.json("./Graphs/Vol_cleaned.json").then(function (data) {
console.log(data);
// Once we get a response, send the data.features object to the createFeatures function
makeMap(data);
makeDrop();
});
//MAKE DROP DOWN MENU TO SELECT VOLCANO NAME
function makeDrop(){
for (var i = 0; i < data.Volcano_Name; i++){
let name = data.Volcano_Name[i];
d3.select("#arr").append("option").text(name);
}
}
function optionChanged() {
makeMap(data);
}
function makeMap(data) {
'''
JSON
I have tried several ways to call the data, I don't think I will be able to describe them correctly being that I am new to the coding world. My current code in the picture provide is working with no errors but nothing is populated in the drop down.

Related

SwiftUI FireStore - Get Field from Document and display as Text()

I'm very new to SwiftUI so bare with me - it's for a project.
I have stored user's details into my Firestore database which looks like this:
image of database
I want to take the name from the database and display it in a Text("Hello" [name])
I have been able to fetch the name from the database and append it into an array. This function is run when the 'Log in' button is clicked.
The code is as follows:
func getData(){
let docRef = db.collection(FStore.collectionName).document(userID)
docRef.getDocument { (document, error) in
if let document = document, document.exists {
if let fetchedName = document.get("name") as? String {
userArray.append(fetchedName)
print(userArray)
}
}
}
}
When printing userArray, the correct name does print.
However I am struggling to display the name outside of the console and on my Text UI field. When I attempt the code below, it gives me an index out of range error.
Text("Hello: \(userArray[0])")
Any help is appreciated / any other methods of retrieving field data from a specific document.
Thanks to #Steve M , it ended up being a kind of silly mistake.
He was right, the display was attempting to read the array before the array had even been populated.
As described in my comments, I called the getData() function then ran code to display the next screen. I wrapped the "display next screen code" in a DispatchQueue to delay the next screen being displayed
DispatchQueue.main.asyncAfter(deadline# .now() + 1){
nextView = true
}
This ran a 1-second delay before displaying the next screen and successfully displayed the name from the database.

Trouble loading eventmarkers from csv file with anychart

I'm trying to make a graph using anygraph. It loads data from a csv file, but i am having trouble to get the eventmarkers from the same file.
I dont seem to get the mapping/source values correct for the eventMarkers.data method. My goal is to load the markers from the same csv file as the source of the graph, where 1 column will contain marker information for some dates.
Suppose i have the following csv:
date, value, optionalmarkerinfo
2021-01-01 01:00:00,2,
2021-01-01 01:00:00,3,markerinfo
and the following code:
anychart.data.loadCsvFile("export.csv", function (data) {
var dataTable = anychart.data.table(0, '');
dataTable.addData(data);
//Create table and stuff
var chart = anychart.stock(); // (the type of graph isnt correct for this data, but its only to generally give a skelet of my setup)
// more stuff where i create the first timelines graph
// then to add a marker on each timeframe:
// (data will be filtered later to only show markers on specific values of dates)
var dataSet = anychart.data.set(data);
var mappingMarker = dataSet.mapAs({date: 0});
chart.plot(1).eventMarkers().data(mappingMarker); // THIS DOESNT WORK
// finish the drawing:
chart.container('container');
chart.draw();
}
Unfortunately, the Stock data and mapping instance are not compatible with the event markers. You should apply the data directly as an array of objects. As a workaround, you can load a separated CSV file, preprocess it to the compatible format and apply it to event markers.
As a reaction to the suggestion of anychart to load a csv with the markers seperately i came to the next solution which worked:
anychart.data.loadCsvFile("markers.csv", function (data) {
var lines=data.split("\n");
var result = [];
for(var i=1;i<lines.length;i++){
var obj = {};
var currentline=lines[i].split(",");
obj["date"] = currentline[0];
obj["description"] = currentline[1];
result.push(obj);
}
// add the markers to the previously defined plot with the markers.
chart.plot(0).eventMarkers({"groups": [
{
"format": "A",
"data" : result
}
]});

How can I retrieve data within an array from an API call in Google script?

I'm pretty new, so bear with me.
I'm making a Google script that will let me call the TMDb API and get some information from a movie list I'm compiling for myself. I'm trying to get all the values to automatically fill by just using the TMDB ID.
After struggling, I found it was easiest to create a function for each column I want to fill (title, date, genre, poster url, etc.) and pass the input from the cell in the spreadsheet to be able to retrieve the info, then return the data to that cell.
I can't figure it out though, when it comes to the "genre" category, because it's in an array.
Here's my code that works for a different column:
function getPoster(input) {
var movieID = input
// Call the TMDB API for movie details
var response = UrlFetchApp.fetch("https://api.themoviedb.org/3/movie/" + movieID + "?api_key=<<mykey>>");
// Parse the JSON reply
var json = response.getContentText();
var data = JSON.parse(json);
return data["poster_path"];
}
Using the API data:
"poster_path":"/hXLScIERphkTsMGdfKKvF4p4SPB.jpg",
However, the "genre" category lists them as an array:
"genres":[{"id":28,"name":"Action"},{"id":18,"name":"Drama"},{"id":53,"name":"Thriller"}],
How can I write the return so that it sends a string with the shown genres "Action, Drama, Thriller" into the single corresponding cell (not spilling into adjacent cells), while also ignoring the "id"?
you need to create an array from the genre's name values.
use this snippet:
var genres = [{"id":28,"name":"Action"},{"id":18,"name":"Drama"},{"id":53,"name":"Thriller"}];
// Return "Action, Drama, Thriller" as a string into a single cell
return genres.map(function(genre){
return genre.name;
}).join(", ");
Sample output when printed:

Populate Google Apps flexTable with filtered Spreadsheet Data and returning changes to spreadsheet

I am writing an application that pulls task data (for a task management system) from rows in a Google Spreadsheet with conditions matching a query. I then send this data into a flexTable next to a checkbox with an onClickHandler as well as a textbox to enter in hours data. Below is the simplest example of how I have achieved this:
\\establish handler for checkboxes that are generated in flexTable
var updateHandler = app.createServerClickHandler('updateTasksfunc');
updateHandler.addCallbackElement(taskTable);
\\search Google Spreadsheet for rows matching condition
for(var i=1; i< taskData.length; i++){
if (taskData [i][1] !=employee){
continue;
}
\\look up if task is already completed, and set checkbox value to true/false
var complete = taskData[i][8].toString();
if(complete==="true"){var checkbox=true;}else{var checkbox=false;}
\\populate flexTable with values from spreadsheet query
taskTable.setWidget(i,0,app.createTextBox().setName('hours'+i).setWidth('50').setId("hour"+i)).setWidget(i,1,app.createCheckBox().setValue(checkbox).setName('complete'+i).addClickHandler(updateHandler)).setWidget(i,2,app.createLabel(taskData[i][2]).setWidth('250')).setWidget(i,3,app.createLabel(taskData[i][3]).setWidth('250')).setWidget(i,4,app.createLabel(taskData[i][4])).setWidget(i,5,app.createLabel(taskData[i][5])).setWidget(i,6,app.createLabel(taskData[i][6])).setWidget(i,7,app.createLabel(taskData[i][7])).setWidget(i,8,app.createTextBox().setVisible(false).setName("dataRow"+i).setValue(i))
}
\edits to doGet()
var numberOfItems = app.createTextBox().setName('rows').setValue(i).setVisible(false);
var rows1 = i+1;
taskTable.setWidget(rows1,0,numberOfItems)
I have stored the spreadsheet data row in the invisible textbox in column 8 of the flex table that I intend to use in the clickHandler function to update the Google Spreadsheet.
I have successfully activated a click handler that runs when a checkbox is clicked; however, I have not yet successfully figured out a way to grab data from the flexTable that I can use to update the Spreadsheet.
//Functional code below
function updateTasksfunc(e){
var app = UiApp.getActiveApplication();
var taskSS = SpreadsheetApp.openById('SPREADSHEETID');
var taskSH = taskSS.getSheets()[0];
var taskData = taskSS.getDataRange().getValues();
var results = [];// an array to collect results
var numberOfItems = e.parameter.rows;
app.add(app.createLabel(numberOfItems));
for(var n=0;n<numberOfItems;n++){
results.push([e.parameter['check'+n]]);// each element is an array of 2 values
}
for(var i=1;i<results.length;i++){
var check = results[i][0];
var row = i+1;
taskSH.getRange(row,9,1,1).setValue(check);
}
return app;
}
I am getting a generic error: cannot find function getRowCount() from generic.
I assume that this means that I am not properly calling my flexTable.
Any thoughts??
flextables are not working like spreadsheets, you can't get widgets values directly as part of the table. You have to get every textBox and checkBox separately using e.parameter.Name.
You can do that easily in a loop but you'll have to know the number of textBoxes to be able to rebuild the names just as you did to create them in the doGet function.
I would suggest to store this number in a tag on one of your widget or in a separate hidden widget (hidden class or invisible textBox). Then you will be able to get the values like this :
...
var results = [];// an array to collect results
var numberOfItems = Number(e.parameter.itemNumbers); // this is the var you are missing right now and need to add. This is the solution of a separate hidden widget
for(var n=0;n<numberOfItems;n++){
results.push([e.parameter['hours'+n],e.parameter['complete'+n]]);// each element is an array of 2 values
}
... // from here you will have an 2D array with all your values and you can continue like you did=.

Is it possible to create a public database (spreadsheet) search with Google Scripts?

I'm trying to create a website where users can come and look for a set of resources, something like a portal, or a database like JSTOR. I am using Weebly; this website will eventually be turned over to someone who does not know computers well, so I'm trying to keep things simple (and free, where doable).
My thought was to use Google Spreadsheets/Forms to handle the input and storage of the data for each individual resources (Title, Author, Type, Topic, Country, etc.), and then find some some method of creating a search function that could placed on the website. Any user could arrive at the site, put in whatever criteria they want to look for, and any resources in the database would be listed out for the user to further investigate. Users would not be adding data to the spreadsheets; only querying it for data.
My first question is such a script/arrangement possible and can it be embedded into a website page? My second question is what would the best approach be?
Yes this is certainly possible, but can achieved in a variety of ways.
One approach you could take with this is to retrieve all the data from the spreadsheet as JSON format and add it to the DOM as a HTML table. Then you can use a nice plugin like dataTables which has a pretty good native search function. I'll give a basic example below.
To retrieve the data you can use Googles spreadsheet JSON API. A basic example is below.
<script src="http://spreadsheets.google.com/feeds/cells/*ID*/*WS*/public/values?alt=json-in-script&callback=*FN*"></script>
Where ID is the spreadsheet's long ID.
Where WS is the worksheet number e.g. 1,2,3 etc.
Where FN is the function you want to call. In my below function i use importGSS
Then I've written the below script that adds the data to a HTML table. It first adds the first row to a <thead> section and then adds the rest to the <tbody> section.
function cellEntries(json, dest) {
var table = document.createElement('table');
var thead = document.createElement('thead');
var tbody = document.createElement('tbody');
var thr;
var tr;
var entries = json.feed.entry;
var cols = json.feed.gs$colCount.$t;
for (var i=0; i <cols; i++) {
var entry = json.feed.entry[i];
if (entry.gs$cell.col == '1') {
if (thr != null) {
tbody.appendChild(thr);
}
thr = document.createElement('tr');
}
var th = document.createElement('th');
th.appendChild(document.createTextNode(entry.content.$t));
thr.appendChild(th);
}
for (var i=cols; i < json.feed.entry.length; i++) {
var entry = json.feed.entry[i];
if (entry.gs$cell.col == '1') {
if (tr != null) {
tbody.appendChild(tr);
}
tr = document.createElement('tr');
}
var td = document.createElement('td');
td.appendChild(document.createTextNode(entry.content.$t));
tr.appendChild(td);
}
$(thead).append(thr);
$(tbody).append(tr);
$(table).append(thead);
$(table).append(tbody);
$(dest).append(table);
$(dest + ' table').dataTable();
}
You can then call back the function with ... where #Destination is the <div> you want to add the HTML table to.
function importGSS(json){
cellEntries(json, '#Destination');
};
Once all completed you'll see something like the below screenshot, the top the final results and the bottom the original spreadsheet. I've edited out some information. I hope this has been of some help.

Resources