accessing user input within the value of an object literal - javascript

These forums are amazing and the contributors I've been helped by are really talented. So I keep coming back everytime I can't solve my own problems or am not understanding a programming concept. This is certainly one of the latter times!
With the help I've received so far, I've managed to develop a complicated form in which the end user will mostly click a series of checkboxes and enter some data into a few textfields. The result of these actions will populate some textboxes with various text, based on the aforementioned actions.
The text that populates the textareas is referenced within a few object literals by each checkbox. This works just fine and the site is quite useable.
In my object literals, I have name:value pairs in which the 'value' is a string of text. I've been trying to include a variable within some name:value pairs to no success. This always breaks the script because the variable is never defined / has a 'null' value on page load.
For example,
Instead of
var example = {
var1:'some string',
var2:'some other string'
}
I tried,
var somevariable = document.getElementById('someId');
var example = {
var1: 'some string' + somevariable + 'some other bit',
var2: 'some other string'
}
My question is whether including a variable referenced elsewhere in the script can be incorporated within the name:value pair in an object literal?
For reference (and because it is a rather long script), my site is: http://www.hematogones.com/bmbiopsies.html.

The trick with an object literal is that it is evaluated immediately; there is no "easy" way to delay the value you get.
var x = "Alice";
var obj = { greeting: "Hello, " + x + "." };
console.log(obj.greeting); // "Hello, Alice."
x = "Bob";
console.log(obj.greeting); // "Hello, Alice."
obj = { greeting: "Hello, " + x + "." };
console.log(obj.greeting); // "Hello, Bob."
Something to come back to later:
If you really really really need to put a variable into a string literal you define later, you could create an inline function. This way, instead of obj.greeting being a simple string, it is a function that you call (which will look like obj.greeting()).This means that instead of the string value being calculated when you declare your object, it will be declared when you call the function. This is a very powerful feature of Javascript called "closures" and you could spend all day learning about the behaviors, expected and unexpected, that you get with them.
var x = "Alice";
var obj = { greeting: function() { return "Hello, " + x + "." }};
console.log(obj.greeting()); // "Hello, Alice."
x = "Bob";
console.log(obj.greeting()); // "Hello, Bob."

The short answer is yes. Here's a working example:
var myStr = "world";
var obj = { var1: "hello " + myStr };
console.log(obj.var1); // Outputs: hello world
As I mentioned in my comment, your specific example has a couple syntax errors, so perhaps just fixing those will correct your issue.

Related

How to compile object inside a string?

I have this string:
const fullname = "my name is ${param.name}"
and this object:
const param = {
name: 'foo'
};
Is there a way to "compile" the string with the object in typescript/javascript?
Why? I want to separate the data from the schema (string).
Both are in separate files so I can't just do: my name is ${param.name}.
I have a function that takes the string and the object and make the output. but there is something like this exist?
The result I expect is:
`my name is foo`
Short answer (one line of code) - yes - it's possible
console.log(new Function('obj', 'return "hello " + obj.name')({ name: 'jackob' }))
Let's break it down to better understand what's happaned:
new Function('obj', 'return "hello " + obj.name')
This will create a new function that accepts a single parameter (as the name implies we are expecting an object). The function body is handling the object and concat it into a string (very similar to what you tried to do)
In order to run it we can use it as an anonymous function or create a reference (e.g. function delegation)
const func = new Function('obj', 'return "hello " + obj.name')
func({ name: 'jackob' }) // here we call the function with a static object as parameter
Because the function return a value (a compiled string) we can get the returned value
const value = func({ name: 'jackob' })
console.log(value)
And one last technical note: if you feel that you are going to compile expressions - I recommend JSONata (here's a specific link to your use-case). It's a great project that unifies your operations over json objects and will help you to get more support during development and in future releases.
Good luck 🍀
You are looking for a template string:
You can use the following syntax:
`my name is ${param.name}`

Give eval a value in JavaScript

very basic JavaScript programmer here!
I was busy on some code with variables that look like this:
blocktype1;
blocktype2;
blocktype3;
blocktype4;
... //everything between blocktype4 and blocktype70, the three dots are not actual code!
blocktype70;
Now I was using eval() in a function where a value was given to one of the blocktype variables. The blocktype depended on the variable "number".
This is what I had for that part:
eval("blocktype" + number) = 3
What I want is, say "number" is 27, then I want the variable blocktype27 to get a value of 3.
When I check the console it says:
ReferenceError: Invalid left-hand side in assignment
Could anyone possibly help me?
I would prefer just vanilla JavaScript and still the use of eval.
Thank you for your time!
The 'correct' solution would probably be to use an Array which is ideal for sequences and are accessible by index.
var number = 1;
var val = 3;
var blocktype = []; // so clean
blocktype[number] = val;
However, properties can be accessed as with the bracket notation as well. This assumes the variables are in global scope and are thus properties of the global (window) object.
var blocktype1; // .. etc
window["blocktype" + number] = val;
The problem with the eval is that is effectively the same as doing f() = 3 which does not make sense: only variables/properties can be assigned to1.
However eval is a built-in function and the results of a function cannot be assigned to, per the error message. It could be written as
var blocktype1; // .. etc (see dandavis' comment)
eval("blocktype" + number + " = " + val);
// What is actually eval'd is:
// eval("blocktype1 = 3")
which quickly exposes a flaw with eval. If val was the string "Hello world!" with would result in eval("blocktype1 = Hello world!") which is clearly invalid.
1 For the gritty: the left-hand side of an assignment has to be a Reference Specification Type, which is a more wordy way of describining the above behavior. (It is not possible for a JavaScript function to return a RST, although it could technically be done for vendor host objects.)
Feel free not to accept this, since it's specifically not using eval(), but:
You can allocate an array of size 71 like so:
var blocktype = new Array(71);
(your number values apparently start at 1, so we'll have to ignore the first element, blocktype[0], and leave room for blocktype[70], the 71st)
You can now assign elements like this:
blocktype[number] = 3;
and use them like so:
alert( blocktype[number] );

creating variable names from parameters in javascript

I was wondering if it is possible to create variable names from parameters passed to a function in javascript. Something like this:
function createVar(number) {
var "number" + number;
}
createVar(1)
I'm new to Stack Overflow and programming, so any help would be appreciated.
You could attach this to the window object, but note it will be global. For example:
function createVar(varName, value) {
window[varName] = value;
}
createVar("test", "Hello World");
alert(test); // Outputs "Hello World".
It is possible to interpret Object as associative array where you specify index and get value by name of index ( hash ):
var x = Array();
x[number] = value;
Single variable name is for programmer, and the code would be hard to maintain and understand when you set variable dynamically in code.
Honestly, I don't see why this would ever be useful, because every time you want to use the variable you'd have to search for it with your number argument.
However, you can do it, albeit not the exact way you had described:
function createVar(number){
eval("var number" + number.toString() + ";");
}
however, this variable will only be accessible within the function, to make it global assign to the window object:
function createVar(number){
window["number" + number] = 15; // creates "global" variable
}
As I've stated before, however, I don't see this being useful, [i]ever[/i], if you want to stratify values by numbers you'd be much better off with an array.

Is it possible to have 2 variables pointing to the same object? (javascript)

I'm trying to have both the variables "my_a" and letters.a point to the same object.
//i want letters.a to reference (point to) my_a, not be a copy...
//expected output should be: letters.a = c
//made variables into Objects.. but didn't help.
var my_a = new Object('a');
var my_b = new Object('b');
var letters = {'a': my_a, 'b': my_b};
$('#output').append('my_a = ' + my_a + '<br>');
$('#output').append('leters.a = ' + letters.a + '<br>');
my_a = new Object('c');
$('#output').append('my_a = ' + my_a + '<br>');
$('#output').append('letters.a = <span style="color:red">' + letters.a + '</span>');
​
See this fiddle:
http://jsfiddle.net/jCsUq/1/
But as you can see by the output, this is not working.
Any ideas? Is this possible with javascript?
Thank you.
The answer to your question is "yes", but I think that your question doesn't describe accurately the thing you're trying to do. What you'd like is for letters.a to be reference to the variable "my_a", in the sense of what one can do in C++ with the & operator. That's not possible in JavaScript.
At the statement:
my_a = new Object('c');
you're giving "my_a" a new, different value. Thus, letters.a still refers to the same thing it did, while "my_a" has changed. There's no way to make a variable or object property "track" another (in JavaScript).
edit — actually it occurs to me that you could do something like what you're looking for by defining a "getter" for the "a" property of "letters", one that returns the current value of "my_a". It'd require that feature in the JavaScript engine you're using, but it'd look something like:
var letters = {};
Object.defineProperty(letters, "a", {
get: function() { return my_a; },
set: function(v) { my_a = v; }
});
IE before IE9 doesn't support that unfortunately. Here's the updated jsfiddle.
You can point 2 variables to the same object or value in javascript like so:
var a = b = {};
// both a and b now reference the same object
Also, there is no need to use the object constructor, curly braces serve as the constructor and save typing. Ie, this:
var a = new Object();
Is equivalent to:
var a = {}
You are confused by the concept of pointers. When you store an object in a variable you actually store the address of that object in the variable.
So, my_a and letters.a both contain the address of the same object. then you change my_a to contain the address of a new object. But letters.a still contains the address of the first object!
So at the end of your script, you have my_a pointing to the object 'c', and letters.a pointing to the object 'a'.
The only way of getting letters.a and my_a to point to the object you call 'c', is to to do
letters.a = my_a
again, setting letters.a to contain the address of the new 'c' object.
By the way, variables holding a more basic type (like ints, char) actually contain the value of the variable itself, not a pointer to the actual data.
Yes, it's possible.
You were in the right direction, but made a small mistake.
When you initialized var letters = {'a': my_a, 'b': my_b};, you inserted the object that my_a pointed to at that moment.
Changing my_a afterwards did not change letters, as it already contains a direct pointer to Object('a').
Yes, it is very much possible and is the default. However, in your code you are modifying the reference (my_a = new Object('c');) when you mean to be modifying the value. This would be more clearly illustrated if you used arrays instead of strings, e.g. my_1 = [23]; my_1[0] = 8;
Why you aren't using such a construct:
var letters = {'a': (new Object('a')), 'b': (new Object('b'))};
It's much more cleaner imho.

What does this Javascript do? `new Function("_", "at" , "with(_) {return (" + text + ");}" )`

What is this line doing:
var tfun = new Function("_", "at" , "with(_) {return (" + text + ");}" );
What is the _, at, and with(_)?
I've read this:
http://www.permadi.com/tutorial/jsFunc/index.html
I understand that it's creating a new function object, but am still quite puzzled at what his is supposed to do.
Forgot to put the source:
http://kite.googlecode.com/svn/trunk/kite.js
http://www.terrainformatica.com/2011/03/the-kite-template-engine-for-javascript/
Here a function is being created that will return the value of the key stored in the variable text on the object passed in to tfun().
When a new Function is created in this manner, the first arguments refer to the parameters of the function and the last argument is the function itself. So here we have two parameters named _ and at and then the function body.
with() is a statement saying to conduct the following lines of code within the context of the object specified. So with(_) is saying to conduct the return statement pulling the key text stored in _.
Here's an example:
var text = "name";
var obj = { "name" : "Bob" };
var tfun = new Function("_", "at" , "with(_) {return (" + text + ");}" );
tfun( obj ); // returns "Bob"
I'm not sure why the at parameter is there as it's not being used.
First comes the function arguments, then code code, so it's basically the same as:
var tfun = function(_, at) {
with(_) { return (eval(text)); };
}
So, whatever is in the text variable will be evaluated and returned from the function.
Note: The use of the eval function should generally be avoided, and as creating code dynamically from a variable does the same thing, it should also generally be avoided. There are a few situations where eval is needed, but most of the time it's not, so you should instead try find out the proper way of doing what you are trying to do.

Categories