When storing an array in local storage, then retrieving the results like this works fine
myarray = ["cat", "dog", 1];
localStorage["storedArray"] = JSON.stringify(myarray);
JSON.parse(localStorage["storedArray"]);
But when i try to store an object array full of Google maps LatLng information all that is printed is [object][object], [object][object] and so on.
localStorage["positions"] = JSON.stringify(this.positions);
JSON.parse(localStorage["positions"]);
Same code just changing the array stored, I know the information in it is fine since Im using it to print lines on the map.
Have you tried the following?
localStorage["positions"] = JSON.stringify(this.positions[0]);
JSON.parse(localStorage["positions"]);
You could try using a console.log to display the [object]. If it has indexes you will need to reference the index as I mentioned in the above example. Open your browser console and see what is the output, and change your code accordingly.
console.log(this.positions);
Hope this helps in some way. Hope you find the answer and share it.
Related
The structure I have for my firebase database is like this:
fruits:
apple,5
banana,6
I want to put apple and banana in an array so that when i give a command to Google Assistant, it would give me apple, 5 and banana, 6. The code I have is like the one below:
function handleCommand(agent) {
return admin.database().ref('Fruits').child().once("value").then((snapshot) =>{
var i;
var fruitlist=[];
//puts each snapshot child of 'Fruit' in an array
snapshot.forEach(function(item) {
var itemVal = item.val();
fruitlist.push(itemVal);
});
//outputs command in google assistant
for (i=0; i < fruitlist.length; i++) {
agent.add(fruitlist[i]);
}
})
The default response is "not available".
I get the following in the execution logs:
Firebase.child failed. Was called 0 aruguments. expects at least 1.
I do not know which argument to put inside the Firebase.child. if i want all fruits to be "spoken" by Google Assistant. Below is a picture of my firebase structure.
The error looks like the one below:
What I am currently doing now to just output the fruits are manually entering each child in the code like this and removed the ".child" in the return statement:
Which gives me the output below which is also what I want to see but using arrays as the solution I am using now is very much hardcoded:
As the error message suggests, and as you surmise, the child() call expects a parameter - in particular, the name of the child node you want to get information from. However, since you want all the children of the "Fruits" node - you don't need to specify it at all. The child() call just navigates down through the hierarchy, but you don't need to navigate at all if you don't want to.
The snapshot you get back will have a value of the entire object. In some cases, this can be pretty large, so it isn't a good idea to get it all at once. In your case, it is fairly small, so not as big a deal.
On the JavaScript side, you can now handle that value as an object with attributes and values. Your original code didn't quite do what you said you want it to, however - you're getting the value, but ignoring the name (which is the attribute name or key). You can iterate over the attributes of an object in a number of ways, but I like getting the keys of the object, looping over this, getting the value associated with the key, and then "doing something" with it.
While I haven't tested the code, it might look something like this:
function handleCommand(agent) {
return admin.database().ref('Fruits').once("value").then((snapshot) =>{
// Get an object with all the fruits and values
var fruits = snapshot.val();
// Get the keys for the attributes of this object as an array
var keys = Object.keys( fruits );
// Iterate over the keys, get the associated value, and do something with it
for( var i=0; i<keys.length; i++ ){
var key = keys[i];
var val = fruits[key];
agent.add( `The number of ${key} you have are: ${val}` );
}
})
While this is (or should be) working Firebase and JavaScript, there are a couple of problems with this on the Actions on Google side.
First, the message returned might have some grammar problems, so using your example, you may see a message such as "The number of Apple you have are: 1". There are ways to resolve this, but keep in mind my sample code is just a starter sample.
More significantly, however, the call to agent.add() with a string creates a "SimpleResponse". You're only allowed two simple responses per reply in an Action. So while this will work for your example, it will have problems if you have more fruit. You can solve this by concatenating the strings together so you're only calling agent.add() once.
Finally, you may wish to actually look at some of the other response options for different surfaces. So while you might read out this list on a speaker, you may read a shorter list on a device with a screen and show a table with the information. Details about these might be better addressed as a new StackOverflow question, however.
I am trying to take the last element in a JSON. I know order is not preserved, but the keys are unix timestamps so I can just sort. I am working from this question:
get last element of a json object in javascript
But I get nothing logged to the console and no errors.
my code:
var mydata = {"1509937402379":"7348.01","1509937412486":"7348.01","1509937422253":"7348.01","1509937426286":"7348.01","1509937430066":"7345.54"}
console.log(mydata[Object.keys(obj).sort().pop()]);
https://jsfiddle.net/Lmb5sd1m/1/
You missed.. .You require to use Object.keys(mydata).
var mydata = {"1509937402379":"7348.01","1509937412486":"7348.01","1509937422253":"7348.01","1509937426286":"7348.01","1509937430066":"7345.54"}
Review same fiddle https://jsfiddle.net/Lmb5sd1m/1/
Broad spectrum apology, to start off with, for any mistakes relating to being a n00b when it comes to code, js, Google Apps Script and indeed stackoverflow.com.
I am trying to extract the polyline from an API call to Google Maps' Directions API. Parsed from the API results, I get:
{routes=[{summary=A215, copyrights=Map data ©2017 Google, legs=[{duration={text=18 mins, value=1108}, start_location={lng=-0.1295712, lat=51.4227696}, distance={text=7.2 km, value=7187}, start_address=London SW16 6ET, UK, end_location={lng=-0.0706306, lat=51.3869032}, duration_in_traffic={text=15 mins, value=882}, end_address=Woodside Green, London SE25 5EU, UK, via_waypoint=[], steps=[{duration={text=1 min, value=6}, start_location={lng=-0.1295712, lat=51.4227696}, distance={text=29 m, value=29}, travel_mode=DRIVING, html_instructions=Head <b>north</b> on <b>Streatham High Rd</b>/<b>A23</b> toward <b>Streatham Common N</b>/<b>A214</b>, end_location={lng=-0.1297011, lat=51.42301399999999}, polyline={points=iozxHxhXo#X}},....
My script is as follows:
function listJourneyPoints(value) {
//Temporary url for var value
var value = "https://maps.googleapis.com/maps/api/directions/json?origin=SW16%206ET&destination=SE25%205EU&mode=driving®ion=UK&departure_time=1507676400&key=AIzaSyDbswrt7RFy3s13ulO9BUY9jQUNchUfi4o";
//Call the google route planner api
var routeResponse = UrlFetchApp.fetch(value);
//Parse JSON from routeResponse
var json = routeResponse.getContentText();
var data = JSON.parse(json);
//Get the polyline
var polyl = data["routes"]["legs"]["steps"]["polyline"];
Logger.log (polyl);
}
I can't work out how to navigate through the arrays and objects to the polyline. I know that dot notation doesn't work with arrays so have used square brackets, but whatever I try I cannot progress past data["routes"]["legs"] without getting 'TypeError: cannot read property "steps" from undefined'. I'm aware the problem probably lies with my not understanding the data structure, but after hours of searching, including using an online Json Parser to elucidate the structure, I'm still stuck, so would be grateful for any help. Thanks!
When working with complicated nested JSON, I like to Logger.log() multiple times as I navigate through it to get a better look at what's going on. Even without that though, adding some formatting to the JSON to see the structure of it and removing unneeded entries can both be helpful in seeing how to access specific elements:
{
routes: [{
legs: [{
steps: [{
polyline: {
points: iozxHxhXo#X
}
}]
}]
}]
}
So the first thing to notice is that routes holds an array, which means we need to access its indices to access the nested objects. Luckily, all of the nested elements are wrapped in an object so we can just access the first element of the array: data["routes"][0]. If I continue to have trouble as I work my way down into the nested objects, I'll keep using Logger.log(data["routes"][0]...) to see what the next key/index should be.
It looks like you had a pretty good idea of the hierarchy and you were just missing the array portion of the objects, which is why you were getting the errors. So adding in [0]'s after each key call should fix your problem.
Also, just as a sidenote, you can use dot notation when accessing keys in an object in Google Scripts, i.e. data.routes[0].legs[0].steps[0].polyline (which returns the polyline object).
I'm currently making a Chrome Extension, and I'm at the last stage of it, storing the users preferences.
I know Local Storage will store strings, and at this stage I'm getting awway with just using strings, but as the storage requirements get bigger, a 2 dimentional array is required. I've seen that Local Storage is not capable of storaing an array, but you can use JSON. I've never used JSON, and when looking at examples, I do not understand how to do so.
for (i=1;i<=localStorage["totalwebsites"];i++) {
// Get the title of the current item
var title = localStorage["websitetitle" + i];
// Create the new context menu item, and get its menuItemId to store in the right localStorage string
var menuItemId = chrome.contextMenus.create({parentId: ParentID, title: title, contexts:["selection"], onclick: searchFromContext});
// Store the created menu items menuItemId in the array so we know which item was chosen later on
websitesarray[menuItemId] = localStorage["websiteurl" + i];
}
As you can see, this gets very messy, very quick, when using strings. I was hoping for totalwebsites to become a count of the items in the array, and websitetitle and websiteurl to be in the 2 dimetional array.
I don't see how you would do this in JSON, or at least how this could be permanently stored in Chrome itself. I'm guessing you'd have to convert it back to Local Storage Strings at some point or something? I don't think I'm getting this.
Any help/pointers would be much appreciated, I can't find much :(
Don't worry, JSON is super easy! Assuming that your websites are stored in websitesarray:
// To load:
websitesarray = JSON.parse(localstorage.websites);
// To store:
localstorage.websites = JSON.stringify(websitesarray);
Make sure you have a sane way to handle the case where localstorage.websites isn't set yet, as JSON.parse will throw a fit if its input is empty.
I am using Greasemonkey/Tampermonkey to visit pages and make a change to a 100-element table based on what's on the current page.
Short term storage and array manipulation works fine, but I want to store the data permanently. I have tried GM_getValue/GM_setValue, GM_SuperValue, localStorage, and indexedDB, but I am clearly missing something fundamental.
Nothing seems to allow me to write the array into the permanent storage and then read it back into a variable where I can access each element, such that variablename[32] is actually the 32nd element in the table (Well, 33rd if you start counting at zero, which I do).
I need access to the entire 100-element table while the script is running, because I need to output some or all of it on the page itself. In the most basic case, I have a for loop which goes from 0 to 99, printing out the value of variablename[i] each time.
I have no predisposition to any method, I just want the frickin' thing to work in a Greasemonkey/Tampermonkey script.
Towards the top of the script I have this:
for (var i = 0; i <= 99; i++) {
currentData[i] = localStorage.getItem(currentData[i]);
}
The purpose of the above section is to read the 100 entries into the currentData array. That doesn't actually work for me now, probably because I'm not storing things properly in the first place.
In the middle, after modifying one of the elements, I want to replace it by doing this:
localStorage.setItem(
currentData[specificElementToChange], differentStuff);
The purpose of the above is to alter one of the 100 lines of data and store it permanently, so the next time the code at the top is read, it will pull out all 100 entries, with a single element changed by the above line.
That's the general principle.
I can't tell if what I'm doing isn't working because of some security issue with Firefox/Chrome or if what I want to do (permanently storing an array where each time I access a given page, one element changes) is impossible.
It's important that I access the array using the variable[element] format, but beyond that, any way I can store this data and retrieve it simply is fine with me.
I think you're going about this wrong. LocalStorage stores strings so the simplest way to store an array in LocalStorage is to stringify it into JSON and store the JSON. Then, when reading it back, you parse the JSON back into an array.
So, to read it in, you do this:
var currentData = JSON.parse(localStorage.getItem("currentData") || "[]");
To save your data, you do this:
localStorage.setItem("currentData", JSON.stringify(currentData));
Working demo: http://jsfiddle.net/jfriend00/6g5s6k1L/
When doing it this way, currentData is a variable that contains a normal array (after you've read in the data from LocalStorage). You can add items to it with .push(), read items with a numeric index such as:
var lastItem = currentData[currentData.length - 1];
Or, change an item in the array with:
currentData[0] = "newValue";
Of course, it's just a normal array, so you can use any array methods on it.