.append or .after defined as a variable? - javascript

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.

Related

How do i dynamically reference an object and its object and property in JS

I'm passing a property options_r into a function but i need to reference to its properties dynamically...
to illustrate in a simple way, here's a function that takes in a parameter.
options_r = {}
function blah(myData,options_r) {
output_data = myData[options_r.target]; //
alert(output_data)
}
THIS WORKS
myData.joe = 'male';
myData.anne = 'female';
let options_r.target = 'joe';
blah(myData, options_r);
THIS DOESNT
myData.dataset.joe = 'male';
myData.dataset.anne = 'female';
let options_r.target = 'dataset.joe';
blah(myData, options_r);
...and yes sometimes in need to reference an object within an object this way.
Any ideas?
Thanks!
What you are trying to acomplish is not a native feature of JavaScript.
Some common extension libraries do that, for example _.get function of lodash. Where in your case if you use this you will be able to do
_.get(myData, options_r.target);
Otherwise, you will have to code something that parse your path and does smart object traversal yourself.
The last option would be to use a solution based around eval but I really wouldn't advise going that route.

Is there a way to tell whether a function parameter was passed as either a literal or as a variable?

I have a function:
function hello(param){ console.log('param is '+param); }
And two calls. First:
hello(123)
Second:
var a=123; hello(a);
Is there any possible way to tell, from within the hello function, whether param was passed as a var or as a literal value?
NOTICE: I am not trying to solve a problem by this. There are many workarounds of course, I merely wanted to create a nice looking logging function. And also wanted to learn the boundaries of JavaScript. I had this idea, because in JavaScript we have strange and unexpected features, like the ability to obtain function parameter names by calling: function.toString and parsing the text that is returned.
No, primitives like numbers are passed by value in Javascript. The value is copied over for the function, and has no ties to the original.
Edit: How about using an object wrapper to achieve something like this? I'm not sure what you are trying to do exactly.
You could define an array containing objects that you want to keep track of, and check if its in there:
var registry = [] // empty registry
function declareThing(thing){
var arg = { value: thing } // wrap parameter in an object
registry.push(arg) // register object
return arg; //return obj
}
function isRegistered(thingObj){
return (registry.indexOf(thingObj) > -1)
}
var a = declareThing(123);
hello(a);
function hello(param){
console.log(isRegistered(param));
}

trying to work dynamically with object properties in javascript

I'm trying to sort out if this is plausible but have gotten syntax errors at best. So I am wondering if it is at all possible.
What I have is an object (example only)
var myObj = {
something1_max:50,
something1_enabled:false,
something1_locked:true,
something2_max:100,
something2_enabled:false,
something2_locked:true,
something3_max:10,
something3_enabled:true,
something3_locked:true
}
and what I want to do through a function is do something like again for example to sum things up..
function displayDetails(theScope, obj)
{
console.log(obj.[theScope]_max);
}
(function(){displayDetails('something3', myObj);})()
so when displayDetails() is called whatever the scope I can see in this example the max for that scope. In the console log for the example I would hope to see 10
Properties of JavaScript objects can always be accessed as a string using the bracket syntax, ie object['property']. This, of course, means you can build that string dynamically:
console.log(obj[theScope + '_max']);
Put the property name string in brackets.
console.log(obj[theScope + '_max']);

JS: using eval on a function while trying to pass an array as parameter, but it throws an error

i want to create a dynamic generated form using javascript, everything works fine, until i try to pass an array as parameter. When i do this, an error happens. Coulr anyone explain what this is?
Heres my code:
var loadFrm = function(component) {
for(nItem in component) {
var myComponent = "add" + firstToUpper(component[nItem].type);
var callComponent = myComponent + "(" + component[nItem].opt + ");";
eval(callComponent);
}
}
var json = [
{
type: "scale",
opt: {content: [{label: "male", value: "m"}, {label: "female", value: "f"}]}
}
];
loadFrm(json);
Edit Here's the error:
missing ] after element list
[Break on this error] addScale([object Object]);
If you use a debugger to look at the string callComponent, you'll probably find it looks something like this:
addScale([object Object])
...which isn't what you want. That's because you're effectively calling toString on your opt object, and the default toString on objects just looks like that. The eval error is because that's invalid syntax.
Generally speaking, any time you think you need to use eval, there's almost certainly a better answer. In this case, it looks like you're trying to call a function and pass in opt. Assuming these functions are "globals", you can do that like this:
var loadFrm = function(component) {
var nItem, functionName;
for (nItem = 0; nItem < component.length; ++nItem) {
functionName = "add" + firstToUpper(component[nItem].type);
window[functionName](component[nItem].opt);
}
}
Live example
Notes on the above:
Don't use for..in to loop through arrays unless you really know what you're doing. for..in does not enumerate the indexes of an array, it enumerates the properties of an object.
We look up the function by name using window[functionName]. This works because "globals" are actually properties of the window object, and you can look up properties using a string name for them using bracketed notation.
Having gotten the function via window[functionName], we just call it directly, passing in the object opt rather than a string form of it. I assume addScale expects to see an object.
I moved all of the vars to the top of the function because that's where they really are (details).
If you can, I'd recommend moving addScale and the related functions to their own object rather than putting them on window. The window namespace is already pretty crowded. Here's the live example modified to not add any symbols to window at all, instead putting the addScale function on an object called functions and using it from there.
Off-topic: The syntax var loadFrm = function(component) creates an anonymous function that it then assigns to a variable. This is used a lot, but unless you're creating different functions based on a condition, e.g.:
var f;
if (...) {
f = function() { ... };
}
else {
f = function() { ... };
}
...it's not actually useful. (If you are creating different functions based on a condition like that, then it's not only useful, it's necessary.) I recommend using named functions whenever possible, because a function with a name helps your tools help you by showing you the function name in error messages, call stacks, etc.
Off-topic 2: You have a variable called json, but FYI, it's not using JSON notation. It's using a combination of JavaScript array and object literal notation, which is a superset of JSON. You'll see a lot of people confused about this, I mention it because you said you're new and so it's worth nipping in the bud. :-) JSON is purely a notation. (A very useful one.)
Use this:
fn = eval(functionName);
fn(objParameter)

constructing javascript variable names at runtime

someFunction(link) {
someOtherFunction('div' + link);
}
By calling someFunction("Test"), the string "divTest" gets passed to someOtherFunction(). But I want the value of the variable "divTest" to be passed.
How can that be done?
Make your variables members of an object. Then you can use [] to access the objects members using a string:
var byname = {
divabc: ...,
divxyz: ...
};
function someFunction(link) {
someOtherFunction(byname['div'+link]);
}
someFunction('abc'); // calls someOtherFunction(byname.divabc)
For this kind of dynamic construction/access of variable names you should use the alternative object notation where:
object.member === object["member"]
This way you could construct your variable name as a string and use it inside square brackets for accessing object members.
eval will do this, but it's usually indicative of some other problem with the program when you want to synthesize identifiers like this. As Ionut says it's better to use the [] notation. I like to link to this whenever questions like this come up.
You should be able to accomplish this with the 'eval' function.
Try this:
var divFoo = "bar";
function someFunction(link) {
someOtherFunction(this['div' + link]);
}
function someOtherFunction(value) {
alert(value);
}
someFunction("Foo");
As wybiral said, all you need is eval:
someFunction(link) {
someOtherFunction(eval('(div' + link + ')');
}
Basically what it does is evaluates the contents of a string as code. Obviously eval is a dangerous little tool since it allows executing arbitrary code so take care when using it.

Categories