So... The problem I have according to the console is:
"Uncaught TypeError: Cannot read property 'title' of undefined
at custom.js:42, at Array.forEach (), at custom.js:39"
How is "title" undefined? What's wrong with my .forEach? (sad noises)
Example of first of six objects in the JSON-array I've built:
var newReleases = [
{
"title":"Honor - Defending the motherland",
"author":"Mark Thomas",
"genre":"Fiction",
"description":"In legislation and formal documents the suffix shire was generally not used: for example, Bedfordshire was referred to as the administrative county of Bedford and the Northamptonshire council as the county council of Northampton.The 1888 Act did not contain a list of administrative counties: it was not until 1933 and the passing of a new Local Government Act."},
For loop with forEach function:
for (var i = 0; i < 6; i++){
newReleases.forEach (function (newReleases) {
var bookTitle = document.getElementsByClassName('card-header')
var t = document.createTextNode(newReleases[i].title);
bookTitle.appendChild(t);
var bookAuthor = document.getElementsByClassName('card-title')
var a = document.createTextNode(newReleases[i].authors);
bookAuthor.appendChild(a);
var cardGenre = document.getElementsByClassName("card-subtitle");
var genre = document.createTextNode(newReleases[i].genre);
cardGenre.appendChild(genre);
var cardDescr = document.getElementsByClassName('card-text');
var p = document.createTextNode(newReleases[i].description);
cardDescr.appendChild(p);
}) //end of forEach
} // end of for-loop
Use either for or forEach(), not both.
for (var i = 0; i < newReleases.length; i++) {
var bookTitle = document.getElementsByClassName('card-header')[0]
var t = document.createTextNode(newReleases[i].title);
bookTitle.appendChild(t);
var bookAuthor = document.getElementsByClassName('card-title')[0]
var a = document.createTextNode(newReleases[i].authors);
bookAuthor.appendChild(a);
var cardGenre = document.getElementsByClassName("card-subtitle")[0];
var genre = document.createTextNode(newReleases[i].genre);
cardGenre.appendChild(genre);
var cardDescr = document.getElementsByClassName('card-text')[0];
var p = document.createTextNode(newReleases[i].description);
cardDescr.appendChild(p);
}
or
newReleases.forEach(function(release) {
var bookTitle = document.getElementsByClassName('card-header')[0]
var t = document.createTextNode(release.title);
bookTitle.appendChild(t);
var bookAuthor = document.getElementsByClassName('card-title')[0]
var a = document.createTextNode(release.authors);
bookAuthor.appendChild(a);
var cardGenre = document.getElementsByClassName("card-subtitle")[0];
var genre = document.createTextNode(release.genre);
cardGenre.appendChild(genre);
var cardDescr = document.getElementsByClassName('card-text')[0];
var p = document.createTextNode(release.description);
cardDescr.appendChild(p);
});
When you use forEach() you don't need to subscript the array variable, you just use the parameter to the callback function.
Related
I'm trying to build a table that the user can hit "new line" to create a new row of the table. I do this by foo.push(document.createElement("INPUT"));
function newLine() {
sArr.push(document.createElement("INPUT"));
sArr[sArr.length-1].setAttribute("type", "text");
document.body.appendChild(sArr[sArr.length-1]);
gArr.push(document.createElement("INPUT"));
gArr[gArr.length-1].setAttribute("type", "text");
document.body.appendChild(gArr[gArr.length-1]);
tArr.push(document.createElement("INPUT"));
tArr[tArr.length-1].setAttribute("type", "text");
document.body.appendChild(tArr[tArr.length-1]);
//alert(sArr.length+", "+gArr.length+", "+tArr.length);
var x = document.createElement("br");
document.body.appendChild(x);
}
function calc(){
var temp = 0;
var total = 0;
for(i = 0; i<sArr.length; i++){
total = total + calc2(i);
}
var o = document.getElementById("output");
o.value = total;
}
function calc2(i){
alert(i);
var s = document.getElementById(sArr[i]);
var g = document.getElementById(gArr[i]);
var t = document.getElementById(tArr[i]);
var VO2walkmin = 3.28;
var VO2rest = 3.05;
var C1 = 0.32;
var C2 = 0.19;
var C3 = 2.66;
var Cdecline = 0.73;
var s2 = s.value;
var g2 = g.value;
var t2 = t.value;
var negGrade = g.value;
if(g2 < 0){g2 = 0};
VO2move = ((C1 * g2)+VO2walkmin)+((1+(C2*g2))*(C3*(s2^2)));
VO2inc = VO2rest+(t2*VO2move);
VO2dec = VO2rest+(Cdecline*(t2*VO2move))
//var o = document.getElementById("output");
return VO2inc;
}
When run, I get the error:
Uncaught TypeError: Cannot read property 'value' of null
from line 66. Specifically, this line:
var s2 = s.value;
I'm struggling to find my mistake here... and all help is appreciated.
You create a new element, but it has no ID. And so you can't fetch it by ID. The result of document.getElementById(sArr[i]) will be null.
Check this answer to see how ID can be assigned to a newly created element:
Create element with ID
There's no need to use document.getElementById. sArr[i] is the input element itself, not its ID, so you can just read its value directly.
var s = sArr[i];
var g = gArr[i];
var t = tArr[i];
I have worked with code that pulls table information off a site and then places into Google Sheets. While this had worked great for months, it has come to my attention that is has randomly stopped working.
I am getting the message "TypeError: Cannot read property "length" from undefined." From code:
for (var c=0; c<current_adds_array.length; c++) {
I have done extensive searching but cannot come to conclusion as to what is wrong.
Full code seen here:
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Get Data')
.addItem('Add new dispatch items','addNewThings')
.addToUi();
}
function addNewThings() {
// get page
var html = UrlFetchApp.fetch("#").getContentText();
// bypass google's new XmlService because html isn't well-formed
var doc = Xml.parse(html, true);
var bodyHtml = doc.html.body.toXmlString();
// but still use XmlService so we can use getDescendants() and getChild(), etc.
// see: https://developers.google.com/apps-script/reference/xml-service/
doc = XmlService.parse(bodyHtml);
var html = doc.getRootElement();
// a way to dig around
// Logger.log(doc.getRootElement().getChild('form').getChildren('table'));
// find and dig into table using getElementById and getElementsByTagName (by class fails)
var tablecontents = getElementById(html, 'formId:tableExUpdateId');
// we could dig deeper by tag name (next two lines)
// var tbodycontents = getElementsByTagName(tablecontents, 'tbody');
// var trcontents = getElementsByTagName(tbodycontents, 'tr');
// or just get it directly, since we know it's immediate children
var trcontents = tablecontents.getChild('tbody').getChildren('tr');
// create a nice little array to pass
var current_adds_array = Array();
// now let's iterate through them
for (var i=0; i<trcontents.length; i++) {
//Logger.log(trcontents[i].getDescendants());
// and grab all the spans
var trcontentsspan = getElementsByTagName(trcontents[i], 'span');
// if there's as many as expected, let's get values
if (trcontentsspan.length > 5) {
var call_num = trcontentsspan[0].getValue();
var call_time = trcontentsspan[1].getValue();
var rptd_location = trcontentsspan[2].getValue();
var rptd_district = trcontentsspan[3].getValue();
var call_nature = trcontentsspan[4].getValue();
var call_status = trcontentsspan[5].getValue();
//saveRow(call_num, call_time, rptd_location, rptd_district, call_nature, call_status);
current_adds_array.push(Array(call_num, call_time, rptd_location, rptd_district, call_nature, call_status));
}
}
saveRow(current_adds_array);
}
//doGet();
function saveRow(current_adds_array) {
// load in sheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
// find the current last row to make data range
var current_last_row = sheet.getLastRow();
var current_last_row_begin = current_last_row - 50;
if (current_last_row_begin < 1) current_last_row_begin = 1;
if (current_last_row < 1) current_last_row = 1;
//Logger.log("A"+current_last_row_begin+":F"+current_last_row);
var last_x_rows = sheet.getRange("A"+current_last_row_begin+":F"+current_last_row).getValues();
var call_num, call_time, rptd_location, rptd_district, call_nature, call_status;
// iterate through the current adds array
for (var c=0; c<current_adds_array.length; c++) {
call_num = current_adds_array[c][0];
call_time = current_adds_array[c][1];
rptd_location = current_adds_array[c][2];
rptd_district = current_adds_array[c][3];
call_nature = current_adds_array[c][4];
call_status = current_adds_array[c][5];
// find out if the ID is already there
var is_in_spreadsheet = false;
for (var i=0; i<last_x_rows.length; i++) {
//Logger.log(call_num+" == "+last_15_rows[i][0]);
if (call_num == last_x_rows[i][0] && call_time != last_x_rows[i][1]) is_in_spreadsheet = true;
}
Logger.log(is_in_spreadsheet);
//Logger.log(last_15_rows.length);
if (!is_in_spreadsheet) {
Logger.log("Adding "+call_num);
sheet.appendRow([call_num,call_time,rptd_location,rptd_district,call_nature,call_status]);
}
}
}
function getElementById(element, idToFind) {
var descendants = element.getDescendants();
for(i in descendants) {
var elt = descendants[i].asElement();
if( elt !=null) {
var id = elt.getAttribute('id');
if( id !=null && id.getValue()== idToFind) return elt;
}
}
}
function clearRange() {
//replace 'Sheet1' with your actual sheet name
var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1');
sheet.getRange('A2:F').clearContent();}
function getElementsByTagName(element, tagName) {
var data = [];
var descendants = element.getDescendants();
for(i in descendants) {
var elt = descendants[i].asElement();
if( elt !=null && elt.getName()== tagName) data.push(elt);
}
return data;
}
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("C:C");
range.setValues(range.getValues().map(function(row) {
return [row[0].replace(/MKE$/, " Milwaukee, Wisconsin")];
}));
Please be careful when instantiating a new array. You are currently using var current_adds_array = Array(). You're not only missing the new keyword, but also, this constructor is intended to instantiate an Array with an Array-like object.
Try changing this to var current_adds_array = []
can someone please let me know, whats wrong with the format of my nested loop. i dont seem to be getting it to loop correctly. the values that are the same are not being generated together.
for (var field in Itemlist) {
for (var field in EstItems){
console.log(Itemlist[field].item_id, EstItems[field].zoho_id);
if (EstItems[field].zoho_id == Itemlist[field].item_id) {
console.log("We are In");
var id = EstItems[field].itemID;
var itemID = EstItems[field].zoho_id;
var barcode = EstItems[field].barcode;
//var EstBarcode = EstItems[field].itemID;
var description = EstItems[field].description;
var cost = EstItems[field].cost;
var shippingCost = "500";
var clearingCharges = "";
var quantityOrdered = 1;
//var quantityRecvd = EstItems[field].itemID;
//var quantityRTD = EstItems[field].itemID;
var selected = 0;
var totalcost = (cost*quantityOrdered)+parseFloat(shippingCost);
var categoryID = 0;
}
}
}
You have a scope problem introduced by overwriting a previous variable.
for (var field in Itemlist) {
// `field` here is a property from ItemList
for (var field in EstItems){
// `field` here is a property from EstItems
// Any attempt to access the `field` var from the outer loop will fail, as it has been overwritten.
}
}
Rename field for either loop.
I am querying a local database and trying to retrieve my data in a form of array of objects to be able to manipulate them in another stage.
Below is my code and the scope I can access my object in and where I fail to access the object.
function setStageOneup(){
var teams = localStorage.teamsUp;
var tournament_id = 1;
var statement = "SELECT * FROM teams WHERE t_id= '"+tournament_id+"';";
localStorage.teamsUp = "";
var team_array = {};
var myTest = callBack(function(val){
var team = {};
for(var i = 0; i < val.rows.length; i++)
{
// teams_array[i]['id'] = val.rows.item(i).id
//console.log(val.rows.item(i).text)
team.id = val.rows.item(i).id;
team.t_id = val.rows.item(i).t_id;
team.m_t_id = val.rows.item(i).m_t_id;
team.name = val.rows.item(i).name;
team.weight = val.rows.item(i).weight;
team.goals = val.rows.item(i).goals;
team.win = val.rows.item(i).win;
team.draw = val.rows.item(i).draw;
team.lost = val.rows.item(i).lost;
team.misc = val.rows.item(i).misc;
team_array[i] = team;
console.log(team); // I am able to hee the output here
}
console.log(team_array); // I am able to hee the output here
},statement);
console.log(team_array); // I am unable to see here even though the variable is decleared in this scope
}
Thank you, if I missed anything please let me know.
I am looping through an array and getting the data that I need.
for (var i = 0; i < finalArray.length; i++) {
var merchName = finalArray[i].merchName;
var amName = finalArray[i].amName;
var amEmail = finalArray[i].amEmail;
var txnID = finalArray[i].transID;
var transAccount = finalArray[i].transAccount;
}
What I am trying to do at this point is only show unique data in the loop.
For example var transAccount could be in the array 5 times. I only one to display that in my table once. How can I go about accomplishing this ?
Final Array is constructed like so; just as an object:
finalArray.push({
transID: tmpTrans,
transAccount: tmpAccount,
amEmail: amEmail,
merchName: merchName,
amPhone: amPhone,
amName: amName
});
var allTransAccount = {};
for (var i = 0; i < finalArray.length; i++) {
var merchName = finalArray[i].merchName;
var amName = finalArray[i].amName;
var amEmail = finalArray[i].amEmail;
var txnID = finalArray[i].transID;
var transAccount = finalArray[i].transAccount;
if(allTransAccount[finalArray[i].transAccount]) {
var transAccount = '';
}
else {
allTransAccount[transAccount] = true;
}
}
var merhcData = {};
var amName = {};
// and so on
for (var i = 0; i < finalArray.length; i++) {
merchData[finalArray[i].merchName] = finalArray[i].merchName;
amName[finalArray[i].amName] = finalArray[i].amName;
// and so on
}
If you are sure, that data in merchName will never be equal amName or other field - you can use one data object instead of several (merchData, amName...)
What you want is likely a Set. (see zakas for ES6 implementation. To emulate this using javascript, you could use an object with the key as one of your properties (account would be a good bet, as aperl said) which you test before using your raw array.
var theSet={};
for (var i = 0; i < finalArray.length; i++) {
var transAccount = finalArray[i].transAccount;
var merchName = finalArray[i].merchName;
var amName = finalArray[i].amName;
var amEmail = finalArray[i].amEmail;
var txnID = finalArray[i].transID;
if(!theSet[transAccount]){
//add to your table
theSet[transAccount]===true;
}
This will prevent entries of duplicate data.