Javascript function not called properly - javascript

I am trying to click on the first radio button and it will assign variables distSelected and weapon some values from the object engDistanceObject. I suspect my HTML might not be written correctly... specifically the input tags.
https://jsfiddle.net/Natronox/sbojaxm4/#&togetherjs=zb80KxkQzm
var engDistanceObject = {
short: ["100m-300m","416 Assault Rifle"],
long: ["300m-1000m","M110 DMR"]
};
var distSelected;
var weapon;
function distanceClick(item){
distSelected = engDistanceObject.item[0];
weapon = engDistanceObject.item[1];
console.log(distSelected,weapon);
};

Use your short and long properties instead of item. You don't have an item property name in your object.
.short[0]
.short[1]

To access dynamic properties, you can't use the . syntax. It ignores variables that might have the same name as the property you're trying to access, and instead will try to access the non-existent item property.
Instead, use the bracket syntax [], which allow a string to be used to access dynamic properties. This means that you need to pass a string as a parameter to your function.
Your HTML event handlers will need quotes around the parameters:
onclick="distanceClick('long')"
And then use the bracket syntax in your JS:
function distanceClick(item){
distSelected = engDistanceObject[item][0];
weapon = engDistanceObject[item][1];
console.log(distSelected, weapon);
}

Related

Setting Variable Assignments with property display

I'm still a novice when it comes to JavaScript and was trying to make my code more cleaner and was wondering why the top scenario works but the bottom doesn't? Am I missing something?
var partner = document.getElementById('partner');
var providedBy = document.getElementById('providedBy');
partner.style.display = "none";
providedBy.style.display = "none";
But this does not?
var partner = document.getElementById('partner');
var providedBy = document.getElementById('providedBy');
collection = partner + providedBy;
collection.style.display = "none";
In the console it gives me error saying Cannot set Property 'display' of undefined. Am I supposed to define it somewhere first? I console logged the new variable and it returned both div elements.
collection is of type string as the + operator automatically call for both their toString() function.
Now what you are trying is to access a property of collection.style which does not exist because you are operating on a string. That's the reason for the error message you are getting.
You could do something like:
var collection = [];
collection.push(document.getElementById('partner'));
collection.push(document.getElementById('providedBy'));
collection.forEach(function(element) {
element.style.display = 'none';
}
which would be something I think you are trying to archive.
just to complement the accepted answer, I think you should understand why you get this error.
For what i understand from your code, you are trying to set the css of both variables partner and providedBy to display : none.
Your first piece of code works because you do this separately, while in your second code you try to add with the (+) operator both nodes, which evaluates to the string "[object HTMLDivElement][object HTMLInputElement]".
Then you try to call .style on that string which evaluates to undefined, and then you try to call display on that undefined value, this is where you get the error.
You could leave your code just like that since there are not too many variables, but if you wanted to do something that worked on multiple variables you could
create an array
push your objects into the array
create a function that loops over the elements of the array and set their style.display = "none" to individually.
In JavaScript you have to declare all of your variables. Secondly, you can't point to two objects at once by using the + operator. JavaScript interprets this as trying to concatenate the two objects, which it can't do in this way. It will return the string [object Object][object Object]
In order to affect two Objects at the same time you would need to create a function or use an existing method.

.append or .after defined as a variable?

So I'm trying to figure out the best way to get this to work. I have a long list of code that's pulling off of a JSON database, and I'm trying to streamline it. I've created the following function:
var insertData = function(formattedData, originalData, referencePoint, insertPoint, insertStyle) {
var formattedData = originalData.replace("%data%", referencePoint);
$(insertPoint).insertStyle(formattedData);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
Is it possible to define a dot function similar to how I have it here - referenced as one of the function's variables? This current code says that insertStyle is not a function - how do I get the code to recognize that insertStyle should be taking a variable name? As in, if my fifth variable called by insertData is append, it should be read as .append.
As a reference, here's how I'm calling the function:
insertData("formattedHeaderName", "HTMLheaderName", bio.name, "#header", "prepend");
Thanks for any assistance or thoughts in advance!
You're looking for a computed property:
$(insertPoint)[insertStyle](formattedData);
Basically, every property access can be represented as a computed property:
foo["bar"]; // same as foo.bar
In your original code, you're using a non-computed property so the interpreter looks for a method literally called "insertStyle", which doesn't exist.
When you pass an argument to a function, like you do in:
insertData("formattedHeaderName", "HTMLheaderName", bio.name, "#header", "prepend");
Those arguments are strings. Not jQuery methods.
So, a solution would be to define all the methods you need to use...
And just compare the string passed to decide.
var insertData = function(formattedData, originalData, referencePoint, insertPoint, insertStyle) {
var formattedData = originalData.replace("%data%", referencePoint);
if(insertStyle=="prepend"){
$(insertPoint).prepend(formattedData);
}
if(insertStyle=="append"){
$(insertPoint).append(formattedData);
}
if(insertStyle=="after"){
$(insertPoint).after(formattedData);
}
// And so on...
}
Maybe there is some other ways to achive this...
But this one is quick and easy to implement.

Javascript remove double quotes in from object's value

I'm generating a JavaScript object in a Java class for use in javascript the result looks like this:
var gridDefinition = {"width":"100%",
"height":700,
"sortable":true,
"columns"[{"datafield":"id","datatype":"string","width":300,"hidden":true,"text":"ID"},
{"datafield":"lastname","datatype":"string","cellsrenderer":"renderer_openEntry","width":300,"text":"Nachname"},
{"datafield":"firstname","datatype":"string","width":200,"text":"Vorname"},
{"datafield":"officePhoneNumber","datatype":"string","width":150,"text":"Telefon"},
{"datafield":"companyName","datatype":"string","width":300,"text":"Firma"},
{"datafield":"mailServer","datatype":"string","width":200,"text":"Mail-Server"},
{"datafield":"mailFile","datatype":"string","width":400,"text":"Mail-Datei"}]} ;
cellsrenderer is a callback function name. How can I remove the doublequotes surrounding renderer_link? The result line should look like this:
{"datafield":"lastname","datatype":"string","cellsrenderer":renderer_openEntry,"width":300,"text":"Nachname"},
How to "remove the quotes" is the wrong question to ask. At the moment the code is running, there are no quotes that can be removed.
What you need is a map that maps a name to a variable, e.g.
var myFunctions = {
renderer_openEntry: renderer_openEntry,
// other functions
};
and then process the object to update the values of all cellsrender proeprties to refer to the value from the map instead of the string:
gridDefinition.columns.forEachfunction(column) {
if (column.cellsrenderer) {
column.cellsrenderer = myFunctions[column.cellsrenderer];
}
});

How to push one Javascript object into another Javascript object?

I have one function in which I am iterating across data object which I have fetched from database. In the foreach loop I am trying to create one object(trigger) and pushing it to another variable(Geo) which I will use to put in another variable(triggers). Below is the code-
var Geo={};
array.forEach(this.cityData,lang.hitch(this, function(data,i){
var trigger = {
type: "Inside",
event: {
name: data.Name,
address:data.Address
}
};
var Location= "Location_"+i;
Geo.Location=trigger; // pushing trigger in Geo variable
}));
var triggers = {
Geo //using Geo in trigger
};
is var triggers={Geo}; equivalent to this below code ?
And is my pushing code Geo.Location=trigger; correct ?
var triggers = {
Geo: {
Location_1: trigger1,
Location_2: trigger2 ...... and so on...
}
};
I didn't tested it but it looks like it does almost the same.
Just one thing:
This should give you an exception:
var triggers = {
Geo //using Geo in trigger
};
The statement should be
var triggers = {
'Geo': Geo //using Geo in trigger
};
otherwise triggers will not have a Geo property.
Geo.Location=trigger; is just fine.
A property in an object accessed through dot notation (obj.property) is always considered simply as the propoerty name - i.e. variables are not evaluated. You can have dynamic property names by using the bracket notation: obj[property], which convert "property" to a string (resolving the variable value if necessary) and uses that as the actual property name.
So, try changin:
Geo.Location
to:
Geo[Location]
Edit: I'm not sure what is the expected final result, but if you want to achieve an object as shown in your last code block, the correct syntax should be:
triggers.Geo = Geo;
again, in consideration of the fact that the "Geo" in the dot notation form is simply the string name of the property, and has no relation to the variable of the same name.

Google Closure Advanced | Object property not recognized | Dynamic Properties?

Actual Error Code
JSC_INEXISTENT_PROPERTY
Summary
I get this error for the code listed and commented below.
I make the call like this. o_p.page holds user input and one of the properties is indeed tag
Mo.AppBAdder.image_element = vDomBMAdd(o_p.page);
o_p.page is populated by calling the object which hold user input like this:
o_p.page = text_object.getArray();
Is there a way I can do this so Google Closure does not feel the property does not exist?
Setting options is O.K. Also, I don't mind modifying the code a bit if needed.
The constructor for text reads in the user input like this:
Su.text = function (form_elements) {
this.text_object = {};
var key;
for (key in form_elements) { //*u
if (form_elements.hasOwnProperty(key)) {
this.text_object[form_elements[key].name] = form_elements[key].value;
}
}
return this;
};
Snippet of Code
function vDomBMAdd(bookmark_object) {
var link_element = document.createElement('a'),
image_element = document.createElement('img'),
page_element = $a('#' + bookmark_object.tag + '_page'), // error here - inexistent property
Reference
Inexistent means same thing as nonexistent
You have two options: create an extern file that declares the 'tag' property or, perhaps more appropriately given how the property is defined, use a quoted property access:
bookmark_object['tag']
Both of these approaches allow you to access "external" properties and are both compatible with ADVANCED optimizations but using an extern file allows you to declare the expected type of the value held by the property and thus provides better type checking.

Categories