dispatchMessage and associative arrays - javascript

I have a problem delivering assiciative arrays to an injected script.
Global.html
var settings = new Array();
settings["accountID"] = safari.extension.settings.getItem("accountID");
settings["accountName"] = safari.extension.settings.getItem("accountName");
settings["accountEmail"] = safari.extension.settings.getItem("accountEmail");
safari.application.activeBrowserWindow.activeTab.page.dispatchMessage("settingsArray", settings);
script.js
switch (msgEvent.name) {
case "settingsArray":
var settings = new Array();
settings = msgEvent.message;
console.log("accountID: " + settings["accountID"]);
break;
When I do it with "normal" arrays, it works fine!
But when delivering associative arrays, I always get "undefined" when calling eg. settings["accountID"]
Does anyone have an idea what's wrong?

You're using arrays when you should be using objects.
var settings = new Array(); // Wrong
var settings = {}; // Right (and better than "new Object()")
You are unnecessarily using the string form of property access.
settings["accountID"] = …; // Works, but too much typing
settings.accountID = …; // Exact same functionality
You only need to use the bracket notation when getting/setting property values if the property name is not a valid JavaScript identifier (e.g. foo["holy!*#$! it works"] = true) or if you need to construct the property name from a variable (e.g. foo["account"+n] = "active";).
You are creating new objects and then throwing them away.
var settings = new Array(); // Makes a new array referenced by a variable
settings = msgEvent.message; // Discards the array and changes the variable
// to reference a new object

Related

How to use a variable for a hash table key in Google Apps Script?

I'd like to use a variable that contains the key value for a hash table in Google Apps Script.
In place of:
var folderRoots = {
"EYFS English":"sdfg0987897sdfga3",
"EYFS Italian":"sdf8f9g7897sfdfg7",
}
var b = folderRoots["EYFS English"]; // gets sdfg0987897sdfga3
I would like to use:
var depEYFSEn = "EYFS English";
var depEYFSIt = "EYFS Italian";
var folderRoots = {
[depEYFSEn]:"sdfg0987897sdfga3",
[depEYFSIt]:"sdf8f9g7897sfdfg7",
}
var b = folderRoots[depEYFSEn]; // gets sdfg0987897sdfga3
However, when attempting to use square brackets for the key variable as suggested here, the editor will throw an error
Invalid property ID
Maybe Google Apps Script Javascript implementation does not support this?
Unfortunately, computed property names are a feature in ES6, and Google Apps Script is still at ES5.
Instead, you can create your keys from your variables by setting the key on the object using bracket notation []:
var depEYFSEn = "EYFS English";
var depEYFSIt = "EYFS Italian";
var folderRoots = {};
folderRoots[depEYFSEn] = "sdfg0987897sdfga3";
folderRoots[depEYFSIt] = "sdf8f9g7897sfdfg7";
var b = folderRoots[depEYFSEn]; // gets sdfg0987897sdfga3
console.log(b);

node.js and jQuery: chained command loops

In jQuery and node.js environments, suppose you have the following:
var object = new Soda().drink("Coke").drink("Pepsi").drink("7Up");
Now let's say I have a list of N drinks and I don't want to hard code this programatically:
var object = new Soda().drink("D1").drink("D2").drink("Dn")...
What is the programatic approach to this problem if I need this to run sequentially and I can't use:
var object = new Soda();
for (var in j){
object.drink(i);
}
The line new Soda().drink("Coke").drink("Pepsi").drink("7Up") implies that .drink() returns a value that by itself is a valid object to call .drink() again with (either the original object, or some other object that encapsulates the modified state).
If that is the case, you could:
var currentDrinkable = object;
for(var drink in drinks) {
currentDrinkable = currentDrinkable.drink(drink)
}

JavaScript Array with multiple items

I am trying to create a array with multiple fields in it.
For Example:
var person1 = {firstname:"Bob", lastname:"Smith", middlename:"happy"};
The problem I have is that I have 5000 variables I want to create so it would become:
var person1 = {firstname:"Bob", lastname:"Smith", middlename:"happy"};
var person2 = {firstname:"John", lastname:"Jones", middlename:"Long"};
..
var person5000 = {firstname:"Jim", lastname:"Cook", middlename:"Shorty"};
I think it would be silly to have 5000 lines of code to declare the variables.
So I want to be able to declare the variables on page load and then later assign the values to each.
I was trying to do this using the following code but I am guessing I am doing something wrong.
(I am loading some dummy data into the variables for testing)
<!DOCTYPE html>
<html>
<body>
<script>
var person = new Array (firstName:"", lastName:"", middleName:"");
for (var i = 0; i < 5000; ++i) {
person[i] = {firstName:"First"+i, lastName:"Last"+i, middlename:"Middle"+i};
}
alert(person1["firstName"]); // should alert First1
alert(person6["lastname"]); // should alert Last6
</script>
</body>
</html>
I was hoping to later in my code set the value using:
(I am pretty sure this code should work, but can't test it since I can't declare the variables correctly)
person1[firstname] = "Terry"; // should replace First1 with Terry
And then to receive a value using:
alert(person1[firstname]); // should alert Terry since it was changed
Anyone know what is wrong with my code since it's not returning the value ?
I am guessing I am declaring the variables wrong? If so how should I declare them ?
You appear to be confused about the difference between arrays and objects in Javascript. Arrays have numeric indexes, objects have named properties. So the initialization
new Array(firstName:"", lastName:"", middleName:"");
makes no sense. Not to mention, it's not valid Javascript syntax; property: value pairs can only be used in object literals, not in argument lists. If you use new Array(...), the argument should either be a single number, which is the size of the array to allocate, or a list of initial array element (with no property: prefixes. But the preferred way to create a new array is simply with the [] literal for an empty array; it will grow as necessary when you assign to it.
When you create an array, you don't get separate variables for each element. You access them using array[n] notation.
// Create an empty array
var person = [];
// Fill up the array
for (var i = 0; i < 5000; ++i) {
person[i] = {firstName:"First"+i, lastName:"Last"+i, middlename:"Middle"+i};
}
// Access elements
alert(person[1].firstName);
alert(person[6].middleName);
// Change elements
person[1].firstName = "Terry";
I believe this should work as you intended:
var person = new Array();
for (var i = 0; i < 5000; ++i) {
person[i] = {firstName:"First"+i, lastName:"Last"+i, middleName:"Middle"+i};
}
alert(person[1]["firstName"]);
alert(person[6]["lastName"]);
As pointed out by others, the person array is filled with objects, not arrays. You can use either property or associative array syntax with them.

javascript wierdness returning value

Hi I am new with javascript, there is a problem that is driving me crazy:
what is the difference between an object staticly declared as this one :
{$or:[{tc_clpar_id:4,tc_par_id:{$in:[79,80]}},{tc_clpar_id:5,tc_par_id:{$in:[105,106]}}]}
and an object costruct at run-time, with this function:
function buildQuery(self,setting,query){
var query = {$or:[]};
cl = 'tc_cl'+self.family+'_id';
att ='tc_'+self.family+'_id';
keys = Object.keys(setting);
for( var k=0;k<keys.length;k++){
ch = keys[k];
var q = {};
q[cl] = ch;
q[att] = {$in:setting[ch]};
query.$or.push(q);
}
return query;
this object is used as query for the node-mongodb-native driver, the first one works, the object return by the function in correct, I checked the two object with assert.deepEqual, there are no errors, but using the produced object I get an empty resultset, I do not have any clue about the problem, I thought maybe something strange with the scope as the function is a method of another object, or maybe with the garbage collector.

Object within object add property with JavaScript

I have an object within an object. It looks like this.
var myLib = {
object1: {}
}
My basic problem is that I wanted to end up like this. So I would like to do this dynamically I will not know the property's or additional objects until run time.
var myLib = {
object1: ({"A1":({"Color":"Blue",
"height":50})
})
}
From reading here on Stack Overflow I know that I can create an object within an object by simply going like this:
myLib.Object1["A1"] = "Something"
But this does not produce what I'm looking for.
I tried this syntax which I know is wrong but basically
mylib.Object1["A1"].["color"]="Blue";
so basically here is the question. I would like to create object "A1" under "mylib.Object" and immediately add property color = "blue" to "A1". I would need to do this for several other properties, but if I can figure out how to do this for one, I can figure it out for the rest. How can I accomplish this task?
No jQuery, please. Just plain old JavaScript is what I'm looking for.**
Once I create the object and properties I would imagine I can just use a for loop to loop through the properties for that object. Like so:
for(key in mylib.Object1["A1"]){}
Right?
You can create it all from scratch like this:
var myLib = {};
myLib.object1 = {};
// assuming you get this value from your code somewhere
var x = "A1";
myLib.object1[x] = {Color: "Blue", height: 50};
Or, if all values are in variables:
var myLib = {};
myLib.object1 = {};
// assuming you get this value from your code somewhere
var x = "A1";
var colorProp = "Color";
var colorPropValue = "Blue";
var heightProp = "height";
var heightPropValue = 50;
myLib.object1[x] = {}; // create empty object so we can then add properties to it
myLib.object1[x][colorProp] = colorPropValue; // add one property
myLib.object1[x][heightProp] = heightPropValue; // add another property
These syntaxes create identical results:
myLib.object1.A1 = {};
var x = "A1";
myLib.object1[x] = {};
The first can only be used when the property name is known when you write the code and when the property name follows the proper rules for a javascript identifier. The second can be used any time, but is typically used when the property name is in a variable or when it doesn't follow the rules for a javascript identifier (like it starts with a digit).

Categories