How do I get the first js object? - javascript

I have this
var markersList = document.getElementById('markersList');
L.MarkerCluster.include({
spiderfy: function(e) {
var childMarkers = this.getAllChildMarkers();
this._group._unspiderfy();
this._group._spiderfied = this;
// Fill the markersList.
markersList.innerHTML = childMarkers
.map((marker, index) => `<li>Marker ${index + 1}:
${marker.getLatLng()}</li>`)
.join('');
// Show the modal.
console.log(markersList);
$(".modalResult").modal('show');
},...
The above gives me in console:
<li>Marker 1: LatLng(45.49934, 9.37966)</li>
<li>Marker 2: LatLng(45.49934, 9.37966)</li>
I need to be able to get as a string 45.49934, 9.37966 since they are the same values, I only need one and I need it as a string as I will have to insert it as an input value later on:
<input type="hidden" value="45.49934, 9.37966">

If I understand your question correctly, then you can extract the lat and lng values from the resut of getLatLng() via the following regular expression:
/(-?\d+.\d*)/gi passed to .match()
This regular expression will extract the two numbers from the result of getLatLng(); one for lat and the other for lng, which can then be combined to aquire the requiredString that you'd use for the input elements value attribute:
{
spiderfy: function(e) {
var childMarkers = this.getAllChildMarkers();
this._group._unspiderfy();
this._group._spiderfied = this;
// Fill the markersList.
markersList.innerHTML = childMarkers.map((marker) =>
`<li>Marker: ${marker.getLatLng()}</li>`).join('');
// If there are any childMarkers
if(childMarkers.length > 0) {
// Match the lat and lng numbers from the string returned by getLatLng()
const [lat, lng] = `${ childMarkers[0].getLatLng() }`
.match(/(-?\d+.\d*)/gi);
// Construct the required string value from the extracted numbers
const requiredString = `${ lat }, ${ lng }`;
// Use requiredString to populate the value attribute of the
// input field in OP
console.log(requiredString);
}
// Show the modal.
console.log(markersList);
$(".modalResult").modal('show');
}
}

You can use children, It like as:
markersList.children[0].innerText

Related

How do you loop through an object and replace text

I have a script that should create a pdf file from a google form submission and grabs the data to be changed as an object. However I am using the replaceText action to make the changes to the doc and I'm getting the following error.
Exception: Invalid argument: replacement
at Create_PDF(Code:37:8)
at After_Submit(Code:13:19)
It is supposed to change the values in the generated doc file and it worked when I used the namedValues function. However now that I'm using range instead it doesn't seem to work.
function After_Submit(e){
var range = e.range;
var row = range.getRow(); //get the row of newly added form data
var sheet = range.getSheet(); //get the Sheet
var headers = sheet.getRange(1, 1, 1, 129).getValues().flat(); //get the header names from A-O
var data = sheet.getRange(row, 1, 1, headers.length).getValues(); //get the values of newly added form data + formulated values
var values = {}; // create an object
for( var i = 0; i < headers.length; i++ ){
values[headers[i]] = data[0][i]; //add elements to values object and use headers as key
}
Logger.log(values);
const pdfFile = Create_PDF(values);
sendEmail(e.namedValues['Email Address to Receive File '][0],pdfFile);
}
function sendEmail(email,pdfFile){
GmailApp.sendEmail(email, "Subject", "Files Attached", {
attachments: [pdfFile],
name: "From Email"
});
}
function Create_PDF(values) {
const PDF_folder = DriveApp.getFolderById("ID_1");
const TEMP_FOLDER = DriveApp.getFolderById("ID_2");
const PDF_Template = DriveApp.getFileById('ID_3');
const newTempFile = PDF_Template.makeCopy(TEMP_FOLDER);
const OpenDoc = DocumentApp.openById(newTempFile.getId());
const body = OpenDoc.getBody();
console.log(body);
body.replaceText("{{Timestamp}}", values['Timestamp'][0]);
body.replaceText("{{Location}}", values['Location'][0]);
body.replaceText("{{Item1}}", values['Item1'][0]);
body.replaceText("{{Item2}}", values['Item2'][0]);
body.replaceText("{{Itme3}}", values['Item3'][0]);
body.replaceText("{{e1}}", values['e1'][0]);
body.replaceText("{{e2}}", values['e2'][0]);
body.replaceText("{{e3}}", values['e3'][0]);
body.replaceText("{{e4}}", values['e4'][0]);
body.replaceText("{{e5}}", values['e5'][0]);
body.replaceText("{{e6}}", values['e6'][0]);
body.replaceText("{{e7}}", values['e7'][0]);
body.replaceText("{{e8}}", values['e8'][0]);
body.replaceText("{{e9}}", values['e9'][0]);
body.replaceText("{{e10}}", values['e10'][0]);
body.replaceText("{{e11}}", values['e11'][0]);
body.replaceText("{{e12}}", values['e12'][0]);
body.replaceText("{{e13}}", values['e13'][0]);
body.replaceText("{{e14}}", values['e14'][0]);
body.replaceText("{{e15}}", values['e15'][0]);
body.replaceText("{{e16}}", values['e16'][0]);
body.replaceText("{{e17}}", values['e17'][0]);
body.replaceText("{{e18}}", values['e18'][0]);
body.replaceText("{{e19}}", values['e19'][0]);
body.replaceText("{{e20}}", values['e20'][0]);
body.replaceText("{{e21}}", values['e21'][0]);
body.replaceText("{{e22}}", values['e22'][0]);
body.replaceText("{{e23}}", values['e23'][0]);
body.replaceText("{{e24}}", values['e24'][0]);
body.replaceText("{{e25}}", values['e25'][0]);
body.replaceText("{{e26}}", values['e26'][0]);
body.replaceText("{{e27}}", values['e27'][0]);
body.replaceText("{{e28}}", values['e28'][0]);
body.replaceText("{{e29}}", values['e29'][0]);
body.replaceText("{{e30}}", values['e30'][0]);
body.replaceText("{{e31}}", values['e31'][0]);
body.replaceText("{{e32}}", values['e32'][0]);
body.replaceText("{{e33}}", values['e33'][0]);
body.replaceText("{{e34}}", values['e34'][0]);
body.replaceText("{{e35}}", values['e35'][0]);
body.replaceText("{{e36}}", values['e36'][0]);
body.replaceText("{{e37}}", values['e37'][0]);
body.replaceText("{{e38}}", values['e38'][0]);
body.replaceText("{{e39}}", values['e39'][0]);
body.replaceText("{{H1}}", values['H1'][0]);
body.replaceText("{{H2}}", values['H2'][0]);
body.replaceText("{{H3}}", values['H3'][0]);
body.replaceText("{{H4}}", values['H4'][0]);
body.replaceText("{{H5}}", values['H5'][0]);
body.replaceText("{{H6}}", values['H6'][0]);
body.replaceText("{{H7}}", values['H7'][0]);
body.replaceText("{{H8}}", values['H8'][0]);
body.replaceText("{{H9}}", values['H9'][0]);
body.replaceText("{{H10}}", values['H10'][0]);
body.replaceText("{{H11}}", values['H11'][0]);
body.replaceText("{{H12}}", values['H12'][0]);
body.replaceText("{{H13}}", values['H13'][0]);
body.replaceText("{{H14}}", values['H14'][0]);
OpenDoc.saveAndClose();
const BLOBPDF = newTempFile.getAs(MimeType.PDF);
const pdfFile = PDF_folder.createFile(BLOBPDF).setName("FLHA");
console.log("The file has been created ");
return pdfFile;
}
Your question was how to loop through an object and replace text
This creates an object from Sheet0:
Sheet0:
one
pattern
two
this is the pattern
three
pattern pattern
four
nothing
five
nothing
Code:
function replacepattern() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet0');
const vs = sh.getRange(1,1,sh.getLastRow(), 2).getValues();
//creating object from spreadsheet
let obj = {pA:[]};
vs.forEach(r =>{
obj[r[0]]=r[1];
obj.pA.push(r[0]);
});
Logger.log(JSON.stringify(obj));
let oA = obj.pA.map(p => [obj[p].replace(/pattern/g,'replacement')]);//doing the replacement in an object
sh.getRange(1,sh.getLastColumn() + 1,oA.length, oA[0].length).setValues(oA);//outputting the replaced string in the next column
Logger.log(JSON.stringify(oA));
}
Sheet0 after running once:
one
pattern
replacement
two
this is the pattern
this is the replacement
three
pattern pattern
replacement replacement
four
nothing
nothing
five
nothing
nothing
This is related to my answer here.
The error code Exception: Invalid argument: replacement at Create_PDF(Code:37:8) at After_Submit(Code:13:19) is caused by the null value of values['Timestamp'][0]. If you try to print the data type of values['Timestamp'], it will return a type object, since that object does not have value for index 0 to it will return a null value.
For entries that are type String, if you add [0] to it, it will return only the first element of the string. Example you have "Test" string, adding [0] to it will return "T"
To fix that, just remove the [0] in all of body.replaceText(..., values['...'][0]) entries.
OR
Loop through values object by replacing the body.replaceText entries in your code with this:
for (const key in values) {
body.replaceText("{{"+key+"}}", values[key]);
}
Example usage:
Form inputs:
Output:
Reference:
JavaScript for..in

Custom function in google sheet using indexOf

I've got a list of emails that I need to clean and identify which of these emails are company emails (i.e info#, hello#, etc)
I've had an idea to add rows in one google sheet, then check this against another google sheet with a column of company alias'. This will then return Trueof False in the column Company Alias? in the Input sheet.
Here is my Google sheet example.
I think it needs to iterate through the values of the second sheet and compare for email 1 field in the first sheet to see if it contains that value. I have made an apps script below:
function CHECKALIAS(x) {
var app = SpreadsheetApp;
var aliasSheet = app.getActive().getSheetByName('Company_Alias').getRange(2, 1, 45, 1);
var aliasRange = aliasSheet.getValues();
var str = x;
if(str.indexOf(aliasRange) !== -1){
return false;
} else {
return true;
}
}
I get the below error:
TypeError: Cannot read property 'indexOf' of undefined (line 13, file "Code")
Are you running the function without passing it a value? It's giving you the error because str has no value.
Anyway, there's no need for a custom function here. This will return true if there's a match with one of the aliases.
=REGEXMATCH(A1, JOIN("|",FILTER(Company_Alias!A2:A, NOT(ISBLANK(Company_Alias!A2:A)))))
str is a string and aliasRange is an array. Instead of searching for the array in the string, you should search for the string in the array.
Another problem is that .getValues​​() returns an array of arrays:
[["info #"], ["support #"], ["sales #"], ...].
To transform it into a 1D array, use the flat() function:
function CHECKALIAS(x) {
let app = SpreadsheetApp;
let aliasSheet = app.getActive().getSheetByName('Company_Alias').getRange(2, 1, 45, 1);
let aliasRange = aliasSheet.getValues().flat(); // Transforms 2D array in 1D
let userDomain = x.split('#'); // split "admin#somedomain.com" into [ "admin", "somedomain.com" ]
let usr = userDomain[0] + '#'; // "admin#
return aliasRange.indexOf(usr) !== -1; // Is usr in aliasRange?
}

How to split array values into new lines - jquery

I have an array that looks like this
array_names = [Mathew,Kelp ,Liman Kolf, Hebert,Ansh];
Now in the array above, Mathew, Kelp is one name , Liman Kolf is another name and Herbet,Ansh is another name making it 3 names in the array.
Now i want to split this array on new lines in table like below
Mathew,Kelp
Liman Kolf
Herbet,Ansh
But with my code as shown below, the table is represented like this
Mathew
Kelp
Liman Kolf
Herbet
Ansh
JS
//how i save to localstorage
$("#myTableID").on("click", "#add-contact", function() {
var values = [];
value = jQuery(this).closest('tr').find('#user-id').text();
values.push(value);
localStorage.setItem('contact_list', values);
}
var array_names = localStorage.getItem('contact_list').split(',');
if(array_names.length)
{
$.each(array_names, function(index, value){
$('#myTableID2').append('<tr><td id="contact">'+value+'</td></tr>');
});
}
Controller
$contacts = Contact::where('firstname','LIKE','%'.$q.'%')->orWhere('lastname','LIKE','%'.$q.'%')->get();
You should split them by a RegExp
const string = 'Mathew,Kelp ,Liman Kolf, Hebert,Ansh';
const array = string.split(/(?: ,)|(?:, )/)
// ["Mathew,Kelp", "Liman Kolf, Hebert,Ansh"]
As suggested by #Khauri, use JSON.stringify() and JSON.parse() to read/write from/to localStorage:
// save values to localStorage
localStorage.setItem('contact_list', JSON.stringify(values));
// retrive values from localStorage
var array_names = JSON.stringify(localStorage.getItem('contact_list'));
// do things with the values
if (array_names.length) {
$.each(array_names, function (index, value) {
$('#myTableID2').append('<tr><td id="contact">' + value + '</td></tr>');
});
}

How to get inner array in javascript

I'm trying to get all the contents from an array.
This is the function that extracts the data for display via innerHTML:
window.location.href = 'gonative://contacts/getAll?callback=contacts_callback';
function contacts_callback(obj) {
var contactinfo = obj.contacts.map(({givenName}) => givenName) + " " +
obj.contacts.map(({familyName}) => familyName) + " " + " (" +
obj.contacts.map(({organizationName}) => organizationName) + ") " +
obj.contacts.map(({phoneNumbers.phoneNumber}) => phoneNumbers.phoneNumber) + "<br>";
document.getElementById("demo").innerHTML = contactinfo;
}
This is an example of what the input looks like when there are only 2 contacts:
{"success":true,"contacts":[
{
"emailAddresses":[],
"phoneNumbers":
[
{
"label":"unknown",
"phoneNumber":"XXX-XXXXXXX"
}
],
"givenName":"John",
"organizationName":"Apple",
"familyName":"Appleseed",
},
{
"emailAddresses":[],
"phoneNumbers":
[
{
"label":"unknown",
"phoneNumber":"XXX-XXXXXXX"
}
],
"givenName":"John",
"organizationName":"Apple",
"familyName":"Appleseed",
},
]
}
I just want the result to be listed as:
John Appleseed (Apple) XXX-XXXXXXX
John Appleseed (Apple) XXX-XXXXXXX
Two issues:
You are displaying all given names, then all family names, ...etc, each with a separate .map() call. Instead only perform one .map() call on the array and then display the properties for each iterated object.
phoneNumbers.phoneNumber is not a correct reference. phoneNumbers is an array, so you should iterate it.
Also:
Template literals make it maybe a bit easier to build the string
You can use .join("<br>") to glue the lines together with line breaks.
Here is a corrected version:
function contacts_callback(obj) {
var contactinfo = obj.contacts.map(o =>
`${o.givenName} ${o.familyName} (${o.organizationName}) ${
o.phoneNumbers.map(n => n.phoneNumber)
}`)
.join("<br>");
document.getElementById("demo").innerHTML = contactinfo;
}
// Demo
var obj = {"success":true,"contacts":[{"emailAddresses":[],"phoneNumbers":[{"label":"unknown","phoneNumber":"XXX-XXXXXXX"}],"givenName":"John","organizationName":"Apple","familyName":"Appleseed",},{"emailAddresses":[],"phoneNumbers":[{"label":"unknown","phoneNumber":"XXX-XXXXXXX"}],"givenName":"John","organizationName":"Apple","familyName":"Appleseed",},]};
contacts_callback(obj);
<div id="demo"></div>
It is hard to give an answer since is hard to tell what you can have in your phoneNumbers array and if you will also display one line for each phone number in that array.
I'll do something like this:
function contacts_callback(obj) {
let arrayContacts = [];
// Iterate over all your contacts
obj.contacts.forEach(item => {
// Iterate over each contact's phone numbers
item.phoneNumbers.forEach(phone => {
// Building your string with string interpolation and pushing to result array
// You could also add <br> or other tags needed here
arrayContacts.push(`${item.givenName} ${item.familyName} (${item.organizationName}) ${phone.phoneNumber}`);
});
});
// Return your array, use it in your innerHTNL, etc.
return arrayContacts;
}
If Your obj is called "obj", than:
const result = obj.contacts.map(contact =>{
return `${contact.givenName} ${contact.familyName} (${contact.organizationName}) ${contact.phoneNumbers[0].phoneNumber}`
}
this code will give back an array of informations that U asked, but if user has more than 1 phone number, it will take only first from the list

Backbone.js filter

I'm trying to get a filter function to work properly. The function takes an array as param. The array containing all the filter params as ints. like for example: [2,36,11]. So the ints represent different filter options. Then i match this array elements with another int that comes as a variable. like 2 for example. so if 2 is in this array the filter should go on and do its thing.
The problem is that this function only works as long as the ints in the array not are higher than 9. So if one of the filter option is 12 it won't work. But lets say the array has an int wich is 1 and you choose the filer on filter option 12 it will accept that as a match and render wathever should be rendered, since indexOf takes it as a match. How can i solve this quite weird behaviour?
filter: function(f) {
var filter = this.collection.filter(function(o){
var accept = false;
$(f).each(function(i,val){
if(_.indexOf(o.get('tags'), val) >-1){
accept = true;
}
})
return accept;
});
var filtered = new PeopleCollection(filter);
new PeopleView({
el: this.$('.peoplelist'),
collection: filtered
});
}
So as tags is a string with the numbers you can split the sting on , and then do a straight comparison on each element against the val.
filter: function(f) {
var filter = this.collection.filter(function(o) {
var accept = false;
$(f).each(function(i, val) {
//only run if accept is false
if (!accept) {
//if tags is a string of numbers spereated by commas
//turn that string into array and test each one against the val
_.forEach(o.get('tags').split(","), function(tag) {
if (accept) {
return;
}
//use parseInt to ensure both are numbers
if (parseInt(tag) === parseInt(val)) {
accept = true;
}
});
}
})
return accept;
});
var filtered = new PeopleCollection(filter);
new PeopleView({
el: this.$('.peoplelist'),
collection: filtered
});
}
here is a quick fiddle using the same base concept, just removed the view part so open your console to see the results of each filter, http://jsfiddle.net/leighking2/gmtvt12p/
This happens because o.get('tags') is returning a String, as you mentioned in a comment.
Your use of _.indexOf(value, item) will work on any value that has a length property and can be accessed with array notation (e.g. value[0]). You can check it by looking at underscore's source code for indexOf function.
The String type of JavaScript fits this signature. You are actually executing your function over each character of the String:
'1,2,3'.length // 5
'1,2,3'[0] // '1'
'1,2,3'[1] // ','
This is why when you have the string "12" it will match either "1" or "2".
To convert your string to an array of numbers, you can do something like this:
'1,2,3'.split(',').map(function(x) { return parseInt(x, 10); }); // [1, 2, 3]
After this conversion, you can use _.indexOf as you expect.
So, try this:
filter: function(f) {
var filter = this.collection.filter(function(o){
var accept = false;
$(f).each(function(i,val){
var tags = o.get('tags').split(',').map(function(x) { // <-
return parseInt(x, 10); // <-
}); // <-
if(_.indexOf(tags, parseInt(val, 10)) >-1){ // <-
accept = true;
}
})
return accept;
});
var filtered = new PeopleCollection(filter);
new PeopleView({
el: this.$('.peoplelist'),
collection: filtered
});
}

Categories