Json access error - javascript

var markers3 = [];
for (var i = 0; i < 1964; i++) {
var dataPhoto = data8.weblandmarks8[i];
if(data8.weblandmarks8[i].ip2==data8.weblandmarks8[i+1].ip2 )
{
var k=i+2;
while(1)
{
if((data8.weblandmarks8[k].ip2) == (data8.weblandmarks8[i].ip2))
k++;
else break;
}
for (var j = i; j < k; j++)
{
var latLng = new google.maps.LatLng(data8.weblandmarks8[j].latitude,data8.weblandmarks8[j].longitude);
var marker = new google.maps.Marker({position: latLng,icon: webicon,title:data8.weblandmarks8[j].webaddress});
markers3.push(marker);
}
i=k-1;
}
}
google maps application
I get the following error in firefox
Error: data8.weblandmarks8[k] is undefined
Source File: file:///Applications/MAMP/htdocs/geo/js/myscript.js
Line: 140
I have defined K but why does firefox say that the json data accessed with it is undefined?
the same data can be accessed with i variable.
edit:
I have a json data file which I am accessing by
its working
but the error is with that specific line only

This calls for some basic debugging first: For what value of k does it fail? What happens if you try to address that value directly?
I'm fairly sure k (being i+2) simply reaches the end of the list at some point - as it stands, the code needs 1966 elements to be present in order to work.

Related

Add contact if contact does not exist under google contacts with “ContactsApp.getContact”

I found the following code as a response to the same question at Check if contact exists under google contacts with "ContactsApp.getContact" but am having some trouble. I am trying to create a Google Script that checks to see if a respondent to a Google Survey already has a contact card in 'System Group: My Contacts' and if not, create a contact card and then add their phone number.
I've updated the following code to reference my fields, but am receiving an error for the line if(emailjson[email.toLowerCase()].id) - which is meant to check to see if that contact existed:
TypeError: Cannot read property "id" from undefined. (line 36, file "Code")
I thought that there was a problem with the IF statement, but I'm not completely familiar with Javascript (or JSON). As an Excel and Access person I'm accustomed to IF statements having a IF something is null, then do this, which so I tried adding === undefined, changing the code to if(emailjson[email.toLowerCase()].id === undefined) but that didn't solve the problem. In looking at the Execution Transcript, it hangs up as soon as it hits someone who doesn't have a contact card.
If I remove new contacts from the beginning of my spreadsheet and go back to the original code (without === undefined), then it creates duplicate contact cards for everyone who already had a card to start with until it reaches the next person who is new, and then it errors out again.
For the people who already have contact cards, I've also received an error on the next line if the phone number in the spreadsheet is just numbers, if(!emailjson[email.toLowerCase()]['phones'][phone.replace(/[_)(\s.-]/g,'')]) {.
TypeError: Cannot find function replace in object 2024313437. (line 37, file "Code")
If I add formatting to the phone number, then it doesn't throw an error (although as I mentioned before, it creates a duplicate contact). Oddly, I I run the function emailsasJSON afterwards, it only shows one contact card as opposed to a duplicate card, even though on the Google Contacts screen I see a contact card for every time I've attempted to run the script.
Thanks in advance for your thoughts.
function emailsasJSON() {
var emailjson = {}
var myContacts = ContactsApp.getContactGroup('System Group: My Contacts').getContacts();
for (var i = 0; i < myContacts.length; i++) {
var emails = myContacts[i].getEmails();
var phonesobj = myContacts[i].getPhones();
var phones = {}
for (var j = 0; j < phonesobj.length; j++) {
phones[phonesobj[j].getPhoneNumber().replace(/[_)(\s.-]/g,'')] = 1;
}
for (var j = 0; j < emails.length; j++) {
emailjson[emails[j].getAddress().toLowerCase()] = {id: myContacts[i].getId(), phones: phones};
}
}
Logger.log(JSON.stringify(emailjson))
return emailjson;
}
function addClient() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetNew = ss.getActiveSheet();
var clientsgroup = ContactsApp.getContactGroup('System Group: My Contacts')
//this is where we will insert the function from above to get the emailjson obj
var emailjson = emailsasJSON()
var contactarray = sheetNew.getDataRange().getValues();
for (var i = 1 ; i < contactarray.length; i++){
var name = contactarray[i][1]
var email = contactarray[i][4]
var phone = contactarray[i][3]
if(emailjson[email.toLowerCase()].id) { //check if email exists
if(!emailjson[email.toLowerCase()]['phones'][phone.replace(/[_)(\s.-]/g,'')]) { //if email exists but phone doesn't, add phone
ContactsApp.getContactById(emailjson[email.toLowerCase()].id).addPhone(ContactsApp.Field.MOBILE_PHONE, phone)
emailjson[email.toLowerCase()]['phones'][phone.replace(/[_)(\s.-]/g,'')] = 1; //add it to the emailjson object in case there are more iterations of this contact in the sheet
}
} else { //add new contact if it doesn't exist
var newcontact = ContactsApp.createContact(name.split(' ')[0],name.split(' ')[1], email)
newcontact.addPhone(ContactsApp.Field.MOBILE_PHONE, phone)
emailjson[email.toLowerCase()]['id'] = newcontact.getId();
emailjson[email.toLowerCase()]['phones'][phone.toString().replace(/[_)(\s.-]/g,'')] = 1;
clientsgroup.addContact(newcontact)
}
}
}
Sample Data:
Your main issue is that your function emailsasJSON() stringified the json object (i.e it was a string) and therefore you could not access successfully the key pair values of the JSON object. To solve this I just parsed the object to make sure it was consistent but as long as you wouldn't have converted it into a string it would have been ok.
The next change is in the first if condition. You don't actually need to check for the id to see if the element exists as just by checking the element itself would do the job (although checking the id would work too).
Finally the way you constructed your json object for the new contact was not done correctly so I have corrected it accordingly to add the appropriate key value pairs.
function emailsasJSON() {
var emailjson = {}
var myContacts = ContactsApp.getContactGroup('System Group: My Contacts').getContacts();
for (var i = 0; i < myContacts.length; i++) {
var emails = myContacts[i].getEmails();
var phonesobj = myContacts[i].getPhones();
var phones = {}
for (var j = 0; j < phonesobj.length; j++) {
phones[phonesobj[j].getPhoneNumber().replace(/[_)(\s.-]/g,'')] = 1;
}
for (var j = 0; j < emails.length; j++) {
emailjson[emails[j].getAddress().toLowerCase()] = {id: myContacts[i].getId(), phones: phones};
}
}
emailjson = JSON.stringify(emailjson);
emailjson = JSON.parse(emailjson);
return emailjson;
}
function addClient() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetNew = ss.getActiveSheet();
var clientsgroup = ContactsApp.getContactGroup('System Group: My Contacts')
//this is where we will insert the function from above to get the emailjson obj
var emailjson = emailsasJSON()
var contactarray = sheetNew.getDataRange().getValues();
for (var i = 1 ; i < contactarray.length; i++){
var name = contactarray[i][1]
var email = contactarray[i][4]
var phone = contactarray[i][3]
if(emailjson[email.toLowerCase()]) { //check if email exists
if(!emailjson[email.toLowerCase()]['phones'][phone.toString().replace(/[_)(\s.-]/g,'')]) { //if email exists but phone doesn't, add phone
ContactsApp.getContactById(emailjson[email.toLowerCase()].id).addPhone(ContactsApp.Field.MOBILE_PHONE, phone)
emailjson[email.toLowerCase()]['phones'][phone.toString().replace(/[_)(\s.-]/g,'')] = 1; //add it to the emailjson object in case there are more iterations of this contact in the sheet
}
} else { //add new contact if it doesn't exist
var newcontact = ContactsApp.createContact(name.split(' ')[0],name.split(' ')[1], email);
var newContactId = newcontact.getId();
var phoneNumber = phone.toString().replace(/[_)(\s.-]/g,'');
ContactsApp.getContactById(newContactId).addPhone(ContactsApp.Field.MOBILE_PHONE, phone);
emailjson[email.toLowerCase()] = {id:newContactId,phones:{phoneNumber : 1}}
clientsgroup.addContact(newcontact)
}
}
}
Reference
Guide for working with JSON in JavaScript

How to hold all the data bound, not just the data of the visible page

First, I'm sorry I do not have enough English Level.
My Grid shows 20 rows on a page. To use Excel export with client template, I used the following source found in the forum.
function excelExportWithTemplates(e) {
var sheet = e.workbook.sheets[0];
var colTemplates = [];
var data = this.dataSource.view();
for (var i = 0; i < this.columns.length; i++) {
if (this.columns[i].template) {
colTemplates.push(kendo.template(this.columns[i].template));
} else {
colTemplates.push(null);
}
}
for (var i = 0; i < colTemplates.length; i++) {
for (var j = 0; j < data.length; j++) {
if (colTemplates[i] != null) {
sheet.rows[j + 1].cells[i].value = colTemplates[i](data[j]);
}
}
}
}
For example, if I have a total of 100 data, only 20 data, the size of one view,
The remainder can not be applied.
it doesn't mean
ExcelExport don't work well, I mean ExcelExport with ClientTemplate do work just only 20rows. (my view page amount)
To do this, add data.Source.View
I tried changing it to total
Total is just counting the number,
No conversion has been made.
To convert all data
What should I turn .view into?
The view() method will return only the rendered data on the viewport. Use the data() method instead, which will return all dataSource's data:
var data = this.dataSource.data();

Returning XML node values

I need to return all XML values from a URL.
I have previously used the URL and it works fine.
This is what I have so far:
function displayXML(xml) {
var devices = xml.getElementsByTagName("device");
for (var i = 0; i < devices.length; i++) {
var deviceDetails = devices[i].children;
for (j = 0; j < deviceDetails.length; j++) {
console.log(devices[i].childNodes[j].nodeValue);
}
}
}
It manages to return the right amount of values: 33 tags 33 values
but it's returning null for each one. However, the XML file contains values for each tag.
Thanks
Based on an answer to this question
The nodeValue property of XML elements is always null. The value of the element is actually stored within text nodes inside the element so you will need to go down one more child to get it. Try this
var devices = xml.getElementsByTagName("device")[i].firstChild.nodeValue;
I think your script should look something like this with firstChild inserted when trying to get the value:
function displayXML(xml) {
var devices = xml.getElementsByTagName("device");
for (var i = 0; i < devices.length; i++) {
var deviceDetails = devices[i].children;
for (j = 0; j < deviceDetails.length; j++) {
console.log(devices[i].childNodes[j].firstChild.nodeValue);
}
}
}

Google Script: Clear content of cells with specific background (to slow)

I am new to Google Script and i got stuck.
The code below works perfectly, but it takes more than 10 min to loop through all named ranges.
It clears the content of cells, but not the one with green backgrounds.
function deletNoGreenCells() {
var namedRange = ['HaM','BeM','LoM']
for (var k=0; k<namedRange.length; ++k) {
var range=SpreadsheetApp.getActiveSpreadsheet().getRangeByName(namedRange[k])
for( var i = 1; i < range.getNumRows()+1; ++i){
for(var j = 1; j<range.getNumColumns()+1;++j){
if (range.getCell(i, j).getBackground()!= "#93c47d") {
range.getCell(i, j).clearContent()
}}}}}
How can i get this faster?
Cheers!
Thank You Matthew for the link to call getBackgrounds, wich leeds me to this solution:
function deletNoGreenCells() {
var namedRange = ['HaM','BeM','LoM']
for (var k = 0; k < namedRange.length; ++k) {
var range =SpreadsheetApp.getActiveSpreadsheet().getRangeByName(namedRange[k])
var backgrounds = range.getBackgrounds();
for(var i = 0; i < range.getNumRows(); ++i) {
for(var j = 0; j<range.getNumColumns(); ++j) {
if (backgrounds[i][j] != "#93c47d") {
range.getCell(i+1, j+1).clearContent()
}
}
}
}
}
Now it runs only 5 seconds. Thanks!
I haven't tried this, but if you're just clearing the data from the non-green cells you might be able to do this:
Call getData on the range to get an array containing all the values
Call getBackgrounds on the range to get the corresponding array of background colours
Use the backgrounds array to update the data array, blanking out the elements you want to clear
Call setData on the range, passing back the modified array
It seems likely that reading and writing the data in big blocks like this will be quicker.

Google Apps Script - TypeError: Cannot read property "0" from undefined

I keep getting an "undefined error" on this line of code:
while (agentSheetValues[j][0] != "") {
... even though if I use Logger.log(agentSheetValues[j][0]) it outputs the variable, so I know it IS defined. I've also tried replacing the while loop with a for loop and have the same problem; what's going on?
Full code below, thank you.
var resultSS = SpreadsheetApp.openById('someKey');
var agentSheet = resultSS.getSheetByName('Agents');
var agentSheetRows = agentSheet.getDataRange();
var agentSheetValues = agentSheetRows.getValues();
var agentSheets = [];
var j = 1;
while (agentSheetValues[j][0] != "") {
var sheetKey = agentSheetValues[j][1];
agentSheets.push(sheetKey);
j++
}
You should consider in your loop that your array of data may end before you reach an empty value. Try this:
var resultSS = SpreadsheetApp.openById('someKey');
var agentSheet = resultSS.getSheetByName('Agents');
//getDataRange returns from A1 to the last column and row WITH DATA.
//you'll not get the whole sheet. Blank rows and columns after the end are ignored
var agentSheetDataRange = agentSheet.getDataRange();
var data = agentSheetDataRange.getValues();
var agentSheets = [];
//I'm assuming you started 'j = 1' on purpose, to skip the header row
//Also, if you're sure you do not have another column with more data than A
// you could drop the:: && data[j][0] != ''
for( var j = 1; j < data.length && data[j][0] != ''; ++j )
agentSheets.push(data[j][1]);

Categories

Resources