How to pass data to DataContext? - leaflet

I have a list of zip codes to loop over to get the lat/lng. How do I pass the object zip to the "success" method so I can assign the lat/lng to the right zip object? Right now by the time I get the results back, I assign them to the wrong zip :-(
I believe the response is the dataContext object but when I tried { zip : zip }, it didn't work. The response contains no such property.
for (var j = 0; j < zipList.length; j++) {
var zip = zipList[j];
L.esri.Geocoding.geocode().postal(zip.Zipcode).run(function (err, results, response) {
alert(response.zip);
}, { zip : zip });
}

As per my understanding the code used to fetch geo location is running asynchronous. I would suggest you to first get all geo location using some waiting loop. Once you get all lat lon than use the forloop to update dB.

Related

How to get files from selected folder with GtkFileChooserButton?

I am making a GTK+3 App with GJS where users select a folder from a GtkFileChooserButton (action property set to select-folder). I want to find all image files in the given folder the user have selected, so I can display one of the images.
I tried this._fileChooserButton.get_files() and this._folderChooseButton.get_uris() but they only return one file, which is the path to the selected folder. Like this:
_init(application) {
this._folderChooseButton.connect('file-set', () => {
this._onFolderChosen();
});
}
_onFolderChosen() {
let folder = this._folderChooseButton.get_file();
// somehow get files from the folder here
this._image.set_from_file(files[1]);
}
From the API it is not really clear to me, how do I find out which image files are inside the user's selected directory (and subdirectories)?
OK, after help from patrick, georges and matthias at guadec, here is what I got.
The get_file() function I tried returns a GFile, which in this case is a folder (in UNIX, folders are also files). In order to get the files within the directory path, we need to call enumerate_children_async() on our GFile, returned by the get_file() function.
The enumate_children_async() function takes five parameters:
A comma-separated attribute list. In our case, since we want the identifiers of the children in the directory, we want to use the attribute called standard::name.
FileQueryInfoFlag: This allows to either follow or not follow symbolic links. In this case, we will use FileQueryInfoFlag.NONE which will not follow symbolic links.
io_priority: How high priority the IO operation should have (we will use GLib.PRIORITY_DEFAULT)
cancellable: A cancellable, which is a way to cancel this operation, in this case we will leave it as null.
callback: This is the function/code you want to run in response to the files having been retreived.
More info on this function is at GJS-Docs at GNOME.org
The enumerate_children_async() function returns a GFileEnumerator, which we can use to retreive a number of the files, by calling next_files_async(), which takes these arguments:
num_files: How many files you want to retreive. In your case, we use 1.
io_priority and cancellable (same as above).
callback: Where we can run a function or code to actually retreive the file.
Below, is the final code for doing this.
const { Gio, GLib, GObject, Gtk } = imports.gi; // import Gio and GLib API at top of your document.
_onFolderChosen() {
let folder = this._folderChooseButton.get_file();
let files = folder.enumerate_children_async(
'standard::name',
Gio.FileQueryInfoFlags.NONE,
GLib.PRIORITY_DEFAULT,
null,
(source, result, data) => {
this._fileEnumerator = null;
try {
this._fileEnumerator = folder.enumerate_children_finish(result);
} catch (e) {
log('(Error) Could not retreive list of files! Error:' + e);
return;
}
this._readNextFile();
});
}
_readNextFile() {
if (!this._fileEnumerator)
return;
let fileInfo = null;
this._fileEnumerator.next_files_async(
1,
GLib.PRIORITY_DEFAULT,
null,
(source, result, data) => {
try {
fileInfo = this._fileEnumerator.next_files_finish(result);
} catch (e) {
log('Could not retreive the next file! Error:' + e);
return;
}
let file = fileInfo[0].get_name();
let filePath = GLib.build_filenamev([this._folderChooseButton.get_filename(), file]);
this._carousselImage.set_from_file(filePath);
});
}

What is the easiest way to import excel/google sheet spreadsheet to a Cloud Firestore database?

I need to import a large table of data into my database in one go. I currently have it as an Excel file but I am happy to copy it to Google sheets etc.
So far I've added a few entries manually directly via cloud firestore.
Is there a solution already out there to achieve this?
I think the easiest way to export table data into Firestore is to use a Google Apps Script Library (for Google Sheets).
Step 1
Make a Copy of THIS example Google Spreadsheet I created as an example
Step 2
From the menu of YOUR copy of the Example Google Spreadsheet from step 1, click Tools > Script Editor. This should open up the example Google App Script associated with the example spreadsheet.
Step 3
Follow the Steps for installing this library and then update the script with the following:
email
key
projectID
These variables are generated by going to the Google Service Accounts page. This will require that you already have a Firebase or Google Cloud account setup. I won't repeat all the steps that are already iterated in in the aforementioned Github writeup. Just follow them carefully, and realize that the private_key is THE ENTIRE KEY starting with -----BEGIN PRIVATE KEY-----\n, EVERYTHING in between, and ending with \n-----END PRIVATE KEY-----\n
Step 4
Insert a page on your spreadsheet that contains your data, and EDIT the script to use your new sheet name and your data. I have HEAVILY commented the script so it's pretty clear what almost every line of code is doing. For those of you that just want to peek at the Google App Script that's behind this spreadsheet, here's the code:
// Note this Script uses an external library as per this page:
// https://github.com/grahamearley/FirestoreGoogleAppsScript
// This solution requires a Google Spreadhseet and a Firebase Account
// FOLLOW THE INSTRUCTIONS ON THAT GITHUB REPO TO SETUP NEEDED API KEYS!!!
//Global Variables
const ss = SpreadsheetApp.getActiveSpreadsheet(); // Gets the active "workbook"
const sheet = ss.getSheetByName('Restaurants'); // CHANGE TO YOUR SHEET NAME
const headerRowNumber = 1; // If you have more than one row for your header, then change this value to number of header rows
// If you want to mark modified cells, then set up a trigger for the following function:
// Edit > Current Project Triggers > (+ Add Trigger) > On Edit Spreadsheet etc
function onEdit(e) {
var cell = ss.getActiveCell(); //This will also effectively get our row
var dataRange = sheet.getDataRange(); //This checks for all rows/columns with data
var modifiedCol = dataRange.getLastColumn()-1; //Our "modified" column should be the second to last
if (cell.getColumn() < modifiedCol && cell.getRow() > headerRowNumber) { //If we edit any cells to the left of our modified column and below our header...
var celltoMark = sheet.getRange(cell.getRowIndex(),modifiedCol) //Get the R/C cordinates of cell to place modified time
celltoMark.setValue(new Date()); //write timestamp to that cell
}
};
// This will parse any comma separated lists you create in any of your fields (useful for search words, or attributes, etc)
function listToArray(list) {
var ogArray = list.split(","); //Input is a comma separated list
let trimmedArr = ogArray.map(string => string.trim()); //Let's strip out the leading/trailing whitespaces if any
return trimmedArr; //return the cleaned array
}
function writeToFireStore() {
const email = 'sheets#yourprojectid.iam.gserviceaccount.com'; // CHANGE THIS!!!
const key = '-----BEGIN PRIVATE KEY-----\nYOURPRIVATEKEY\n-----END PRIVATE KEY-----\n'; // CHANGE THIS!!!
const projectID = 'yourprojectid'; // CHANGE THIS!!!
var firestore = FirestoreApp.getFirestore(email, key, projectID);
const collection = "MySpreadsheetData"; // Name of your Firestore Database "Collection"
var dataRange = sheet.getDataRange().offset(headerRowNumber, 0, sheet.getLastRow() - headerRowNumber); //this is your data range
var data = dataRange.getValues(); // this is an array of your datarange's values
var lastCol = dataRange.getLastColumn(); // this is the last column with a header
var newDoc = {}; // Instantiate your data object. Each one will become the data for your firestore documents
// r = row number in this case
for (let r = 0; r <= dataRange.getLastRow(); r++) {
//Logger.log("R = ",r);
var cellMod = dataRange.getCell(r+1, lastCol-1);
var cellFS = dataRange.getCell(r+1, lastCol);
var cellModVal = cellMod.getValue();
var cellFSVal = cellFS.getValue();
//
// IMPORTANT READ THIS IMPORTANT READ THIS IMPORTANT READ THIS IMPORTANT READ THIS IMPORTANT READ THIS!!!
// Well, read the line below...
if (r > 2) break; //Comment Out this line after you're done testing otherwise you'll write all your rows to firestore after every run
newDoc[r] = {
name : data[r][1],
category : data[r][2],
cuisine : data[r][3],
address: {
add1: data[r][4],
add2: data[r][5],
city: data[r][6],
state: data[r][7],
zip: data[r][8]
},
tel: data[r][9],
searchterms: listToArray(data[r][10]) //Let's turn a csv list into an array
}
// For the sake of efficiency and to save $, we WON'T create documents that have already been created...
// ...and we won't update documents that have a fireStore Timestamp that's newer than a Modified Timestamp
// If there's not firestore timestamp in our spreadsheet, then let's create firestore document and update firestore stamp:
if (!cellFSVal) {
var now = new Date(); //Generate timestamp right now
try {
firestore.createDocument(collection + "/" + data[r][0], newDoc[r]); // To Use Your Own Document ID
//Now let's insert a timestamp in our Firestore TS column of the sheet so we know it's been added to Firestore
cellFS.setValue(now);
Logger.log("Row ",r,"(",data[r][1],") is NEW and was added to FireStore Successfully");
} catch (e) {
Logger.log("Error: ",e," : Document with same name already existed in Firestore.");
}
}
//var if FS Timestamp exists but, the modified time stamp is greater, let's update the Firstore Document
else if ((cellFSVal) && (cellModVal > cellFSVal)) {
try {
firestore.updateDocument(collection + "/" + data[r][0], newDoc[r]);
//Now let's insert a timestamp in our Firestore TS column of the sheet so we know it's been updated to Firestore
cellFS.setValue(now);
Logger.log("Row ",r,"(",data[r][1],") updated/edited.");
} catch (e) {
Logger.log("Error: ",e," : Document existed, we tried updating it, but jack shit happened.");
}
}
else {
Logger.log("Row ",r,"(",data[r][1],") Already in Firestore & hasn't been modified. Skipped.");
}
}
}
Step 5
Once your script is modified to your needs, it's time to run the script. Simply save it (File > Save), then choose the function "writeToFireStore" from the "Select function" dropdown selector in the menu bar (in between the icon of the bug, and the lightbulb), then hit the PLAY icon (to the left of the bug icon). At this point, you will likely be prompted to accept permissions to run the script, (which you need to accept if you want to run the script). Once you've accepted the permissions, then run the "writeToFireStore" function again if it hasn't already run, and voila!
NOTES:
I created a function that automatically writes a Modified Timestamp to the second to last column in the target sheet, and when you run the function, writes a Firestore Timestamp (so you know which rows have been successfully exported to Firestore). This way, if you run the firestore function again, and you haven't changed the data on your sheet, it won't bother updating the database with the same data (and will save you money and/or server resources). For this functionality to work, you must setup project Triggers (which is explained inside the script in the comments).

Protractor - Create a txt file as report with the "Expect..." result

I'm trying to create a report for my scenario, I want to execute some validations and add the retults in a string, then, write this string in a TXT file (for each validation I would like to add the result and execute again till the last item), something like this:
it ("Perform the loop to search for different strings", function()
{
browser.waitForAngularEnabled(false);
browser.get("http://WebSite.es");
//strings[] contains 57 strings inside the json file
for (var i = 0; i == jsonfile.strings.length ; ++i)
{
var valuetoInput = json.Strings[i];
var writeInFile;
browser.wait;
httpGet("http://website.es/search/offers/list/"+valuetoInput+"?page=1&pages=3&limit=20").then(function(result) {
writeInFile = writeInFile + "Validation for String: "+ json.Strings[i] + " Results is: " + expect(result.statusCode).toBe(200) + "\n";
});
if (i == jsonfile.strings.length)
{
console.log("Executions finished");
var fs = require('fs');
var outputFilename = "Output.txt";
fs.writeFile(outputFilename, "Validation of Get requests with each string:\n " + writeInFile, function(err) {
if(err)
{
console.log(err);
}
else {
console.log("File saved to " + outputFilename);
}
});
}
};
});
But when I check my file I only get the first row writen in the way I want and nothing else, could you please let me know what am I doing wrong?
*The validation works properly in the screen for each of string in my file used as data base
**I'm a newbie with protractor
Thank you a lot!!
writeFile documentation
Asynchronously writes data to a file, replacing the file if it already
exists
You are overwriting the file every time, which is why it only has 1 line.
The easiest way would probably (my opinion) be appendFile. It writes to a file without overwriting existing data and will also create the file if it doesnt exist in the first place.
You could also re-read that log file, store that data in a variable, and re-write to that file with the old AND new data included in it. You could also create a writeStream etc.
There are quite a few ways to go about it and plenty of other answers
on SO specifically on those functions that can provide more info.
Node.js Write a line into a .txt file
Node.js read and write file lines
Final note, if you are using Jasmine you can also create a custom jasmine reporter. They have methods that contain exactly what you want (status Pass/Fail, actual vs expected values etc) and it's fairly easy to set up with Protractor

Using JSZip to extract multiple KML files for Leaflet VectorGrid

The map uses KML files to generate a single geoJSON object to pass to VectorGrid's slicer function. To improve performance, the files are served as a single KMZ and extracted using the JSZip library. We then loop through each file (KML), parse it and convert to geoJSON. The features are concatenated to a separate array which is used to create a final geoJSON object (a cheap way of merging).
var vectorGrid;
JSZipUtils.getBinaryContent('/pathto/file.kmz', function (error, data) {
JSZip.loadAsync(data).then(function (zip) {
var featureArray = [];
zip.forEach(function (path, file) {
file.async('string').then(function (data) {
// convert to geoJSON, concatenate features array
featureArray = featureArray.concat(geoJSON.features);
}
}
var consolidatedGeoJSON = {
'type': 'FeatureCollection,
'features': featureArray
};
vectorGrid = L.vectorGrid.slicer(consolidatedGeoJSON, options);
}
}
The idea was that once that operation was complete, I could take the final geoJSON and simply pass it to the slicer. However, due to the nature of the promises, it was always constructing the slicer first and then parsing the files after.
To get around this, I was forced to put the slicer function inside the forEach, but inside an if statement checking if the current file is the last in the zip. This allows the vectors to be drawn on the map, but now I can't enable a hover effect on each layer separately (each KML contains a specific layer used as an area outline for interaction).
The vectorGrid slider options allows you to specify a getFeatureId function, but I don't understand how to pass that id to the setFeatureStyle function in the event handlers.
The basic problem is that you try to assign value to vactorGrid before you assigned value to featureArray. I think that you need to use Promise.all(..). Something like that:
var zips=[];
zip.forEach(function(path,file) {
zips.push(file.async('string');
});
Promise.all(zips).then(function(data){
return data.map(function(value){
return value.features;
});
}).then(function(featureArray) {
vectorGrid = L.vectorGrid.slicer(
{type:'FeatureCollection',feature:featureArray}, options);
});

How to parse json object in UnityScript?

I am following this link http://wiki.unity3d.com/index.php/JSONUtils but not able to parse json object.
What I have tried so far:
function SerializeObject()
{
var object = {"response":[{"id":"100","name":"Guest","score":"14","game":"3,6,9,7,1,8,2,4","date":"2015-02-28 11:22:32"},{"id":"99","name":"Guest","score":"18","game":"7,8,2,5,6,9,4,3","date":"2015-02-28 11:19:35"},{"id":"89","name":"Guest","score":"17","game":"5,7,2,8,6,1,3,9","date":"2015-02-26 16:39:59"},{"id":"96","name":"Guest","score":"18","game":"2,6,1,5,9,7,8,4","date":"2015-02-26 16:34:05"},{"id":"97","name":"Guest","score":"16","game":"1,7,3,4,8,2,6,5","date":"2015-02-26 16:32:30"},{"id":"95","name":"Guest","score":"14","game":"1,3,7,4,6,9,2,8","date":"2015-02-23 19:20:07"},{"id":"90","name":"Guest","score":"16","game":"8,3,9,6,4,5,2,7","date":"2015-02-23 16:48:55"},{"id":"92","name":"Guest","score":"17","game":"5,2,1,9,7,4,3,8","date":"2015-02-23 16:48:28"},{"id":"91","name":"Guest","score":"16","game":"2,1,3,9,6,7,8,4","date":"2015-02-23 16:48:06"},{"id":"94","name":"Guest","score":"14","game":"5,2,8,7,6,1,9,4","date":"2015-02-23 16:47:25"},{"id":"93","name":"Guest","score":"16","game":"8,9,2,7,4,6,3,1","date":"2015-02-23 16:45:44"},{"id":"88","name":"jacky chain","score":"15","game":"1,2,5,4,7,9,3,6","date":"2015-02-23 13:35:20"},{"id":"87","name":"Genie","score":"15","game":"8,9,5,7,1,4,2,3","date":"2015-02-22 16:19:32"},{"id":"86","name":"Genie","score":"15","game":"9,7,3,2,1,5,8,4","date":"2015-02-22 16:16:13"},{"id":"85","name":"Genie","score":"15","game":"7,1,4,6,5,3,9,8","date":"2015-02-22 14:25:39"},{"id":"83","name":"new","score":"18","game":"2,5,4,1,8,9,7,6","date":"2015-02-22 11:11:49"},{"id":"84","name":"Guest","score":"15","game":"9,8,3,5,1,4,2,7","date":"2015-02-22 09:48:28"},{"id":"80","name":"Guest","score":"16","game":"5,4,2,3,1,8,7,6","date":"2015-02-22 08:24:55"},{"id":"82","name":"Guestr","score":"15","game":"8,1,9,5,7,4,6,3","date":"2015-02-21 21:00:37"},{"id":"81","name":"Guest","score":"18","game":"9,4,2,7,6,5,1,8","date":"2015-02-21 20:54:51"},{"id":"79","name":"Guest","score":"15","game":"2,6,9,5,8,3,1,7","date":"2015-02-21 20:37:30"},{"id":"78","name":"Guest","score":"15","game":"3,6,9,7,1,5,4,2","date":"2015-02-21 20:35:27"},{"id":"77","name":"Guest","score":"17","game":"5,3,7,9,8,4,1,6","date":"2015-02-21 16:04:17"},{"id":"64","name":"Guest","score":"17","game":"7,9,8,4,6,1,3,5","date":"2015-02-21 16:03:41"},{"id":"76","name":"new","score":"18","game":"9,3,4,8,6,5,2,1","date":"2015-02-21 15:27:25"}]};
for( var test in object.Keys )
{
Debug.Log( "Object["+test+"] : "+object[test] );
}
}
I see the below line in the Log:
Object[response] : Boo.Lang.Hash[]
Now i want to extract value from this object.
I would appreciate your help on this, thank you.
Your log message is telling you that object["response"] is returning an array of hashes as you would expect from the JSON you parsed. Now you need to iterate over that array which will give you each internal hash object, the first one being:
{"id":"100","name":"Guest","score":"14","game":"3,6,9,7,1,8,2,4","date":"2015-02-28 11:22:32"}