Trouble getting value from function to new variable - javascript

I can't figure out why the functions return is not being grabbed by “var”. I am using a select object to pass the parameter:
<select name="BILLTOSTATE" onchange="setBTS(this) >
<option value="Alabama">Alabama</option>
<option value="Alaska">Alaska</option>
ETC….
Function I would like to receive that value:
function setBTS(val){
var lv_bts = val.value;
return lv_bts;
}
And lastly the VAR I would like to set from setBTS function:
var lv_bts = setBTS();
Also I don’t know if it matters, but the new VAR lv_bts is located inside another function. Thanks. Sorry for this question. I'm new to this and I’m sure the answer is easy and in my face!

function setBTS takes a parameter as an argument, when you call it you would also need to supply that parameter in order to receive it back.
Think of it like this:
function myFunction(necessaryArgumentForFunction) {
let internalVariable = necessaryArgumentForFunction.value;
return internalVariable;
}
let variable = { value: 'some value' };
cont lv_bts = myFunction(variable);
console.log(lv_bts);
EDIT - (same day)
Add some details on question formatting in relation to thread below
When you are setting up a question either concisely explain anything you aren't showing or add code snippets.
For Example:
This method is being called by an event handler which is passing its state (this/event) in as an argument.
Or:
let ele = document.getElementById('myEle');
ele.onChange = setBTS;
Also a good idea to add any failed strategies you have attempted (with results) to save you and people trying to help some time
I personally also like to include any technologies I'm using that may be relevant with versions (eg Node v8.1.4, npm v5.3.0) sometimes it helps surface known issues or idiosyncracies that might not be immediately apparent if you aren't as familiar with the library.
Anyway, I hope that helps :D. Have a good one.

setBTS is expecting an argument; you aren't passing one.

setBTS(val) is expecting a parameter, which is not passed when you are calling the function, Hence val.value will be undefined since val is undefined

Related

running code in another function's scope (JavaScript)

So I'm working on a sort of JavaScript framework, just some utility things for myself to use in future projects, and I want to make a data binding system.
The first method I used was objects, and the code would just loop through the specified html element and look for occurences of {{key}} in the markup and then look for that key in the object and replace it that way in the HTML.
For example, if you had <div>{{name}} is a cool guy</div> in the HTML and had {name:"joseph"} in the JS then the final product would be displayed on screen as 'joseph is a cool guy'.
However, I decided later to change my method and instead the framework would except a function. So instead of {name:"joseph"} you would give it function(){ var name = "joseph" }.
This obviously looks better and gives a lot better functionality.
I changed the processing function so instead of looking for the key/value pair to replace the {{key}}, it just uses eval on the variable to gets its value.
My problem lies here: How do I run my search/replace code INSIDE the scope of the function the user passes.
If the user defines variables within that function, their values will not be available anywhere else due to scope issues.
I've tried using Function.toString() to actually modify the source code of the function, but nothing's working and it's all very complicated.
(The issues are not due to the actual solution, I think that Function.toString() might work, but due to my implementation. I keep getting errors)
So... What is the best way to run arbitrary code in the scope of another function?
Critera:
Obviously, I can't modify the function because the user is passing it in. (you can't just tell me to add the search/replace code to the bottom of the function)
The variables must stay in the local scope of the function. (no cheating by using window.name = "joseph" or anything)
I am also aware of how terrible eval is so any suggestions as to get it to work are greatly appreciated. Thanks!
Code:
function process(html) {
var vars = html.match( /({{)[^{}]*(}})/g )
// vars = ['{{variable}}', '{{anotherVariable}}']
var names = vars.map( function(x){ return x.replace("{{", "").replace("}}", "") } )
// names = ['variable', 'anotherVariable]
obj = {}
for (var i = 0; i < names.length; i++) {
obj[names[i]] = eval(names[i])
}
for (var p in obj) {
html = html.replace(new RegExp('{{'+p+'}}','g'), obj[p]);
}
return html
}
You should go back to your first method with the object, it's much better. You can still pass a function, but the function should return an object:
function () {
return { name: 'joseph' }
}

Calling an Arg twice in Ramda

I am building a simple application using Ramda.
I have run into a functional composition problem that I am not really sure how to address without creating what seems to be a needlessly absurd function.
The scenario:
I have an object being passed as a parameter. There are two attributes on this object, and some other stuff that isn't relevant to the problem other than that I'd like to not change it's state :
{locCode :<string>, LocationList : [<Location>], someOtherParams : ... }
I have a single arg function which can convert a locCode to a location:
fetchLocByCode
My desired result here would be to take the locCode value, pass it to fetchLocByCode, append LocationList with the result, and return a new object with the new LocationList without touching anything else on the object.
Something analagous to:
(Param)=>{
Param.LocationList.push(fetchLocByCode(Param.locCode));
return Param;
}
What I've ended up writing to do this seems extremely ridiculous and leads me to believe I have done something horribly wrong:
const locListLens = R.lens(R.prop('LocationList'),R.assoc('LocationList'))
const appendLocList = (i)=>R.compose(R.over(locListLens),R.append,fetchLocByCode,R.prop('locCode'))(i)(i)
This solution 'works' but it seems as if I've missed some fundamental idea.
Would anyone care to present a more 'canonical' way to address this scenario?
Let's start with your initial version:
Param => {
Param.LocationList.push(fetchLocByCode(Param.locCode));
return Param;
}
I very much hope the mutation is not required. Let's remove it:
Param =>
R.assoc('LocationList',
R.append(fetchLocByCode(Param.locCode), Param.LocationList),
Param)
We could use a lens to avoid accessing the LocationList property twice:
Param =>
R.over(R.lensProp('LocationList'),
R.append(fetchLocByCode(Param.locCode)),
Param)
Could we get rid of Param entirely? Let's start by using R.converge:
R.converge(R.over(R.lensProp('LocationList')),
[Param => R.append(fetchLocByCode(Param.locCode)),
R.identity])
Let's use R.compose to remove Param from the first branching function:
R.converge(R.over(R.lensProp('LocationList')),
[R.compose(R.append, fetchLocByCode, R.prop('locCode')),
R.identity])
Any time you find yourself writing R.converge(f, [g, R.identity]) you've discovered a use for the S combinator!
S.S(R.flip(R.over(R.lensProp('LocationList'))),
R.compose(R.append, fetchLocByCode, R.prop('locCode')))
Although this is neat, I think the R.assoc version is fine. Future readers would not enjoy having to make sense of S.S(R.flip(R.over(R.lensProp. ;)

In CoffeeScript, how do you pass a function as an argument of a function, which also in turn takes an argument?

I don't know how to phrase it properly so I can't find answers by Google, but here's basically my problem:
I want my CoffeeScript to output something like this in JS: (I'm developing a Node app)
var someapp = require('someapp')
var another = require('another')
someapp.configure(function() {
someapp.use(another.do('argument'));
});
So I wrote it this way in CoffeeScript:
someapp = require 'someapp'
another = require 'another'
someapp.configure () ->
someapp.use another.do 'argument'
But instead, I'm getting this output:
some.configure(function() {
return someapp.use(another["do"]('argument'));
});
Obviously, my biggest problem is the line return someapp.use(another["do"]('argument')); I can't find in the CoffeeScript docs or elsewhere the proper syntax, so I'm hoping someone can point me to the right direction. Thanks in advance.
According to the docs,
CoffeeScript provides the do keyword, which immediately invokes a passed function, forwarding any arguments.
So, coffeescript outputs another["do"] to avoid using the do reserved keyword.
Furthermore, in this case, the function another.do is an object property that happens to be a function. It can be accessed by using both another.do() and another["do"]().

Javascript - Passing arguments to function

I've always passed arguments to a function like so:
setValue('foo','#bar')
function setValue(val,ele){
$(ele).val(val);
};
Forgive the silly example. But recently I have been working on a project that has some functions that take a lot of arguments. So I started passing the arguments through as an object (not sure if that's the correct way to put that), like so:
setValue({
val:'foo',
ele:'#bar'
});
And then in the function:
function setValue(options){
var value = options.val;
var element = options.ele;
$(element).val(value);
};
My question is, is there a better way to do that? Is it common practice (or okay) to call these 'options'? And do you typically need to 'unpack' (for lack of a better term) the options and set local vars inside the function? I have been doing it this way in case one of them was not defined.
I'm really looking to not create bad habits and write a bunch of code that is ugly. Any help is appreciated and + by me. Thanks.
I do the exact same thing, except I don't declare a new variable for each option inside the function.
I think options is a good name for it although I shorten it to opts.
I always have a "default" object within the function that specify default values for each available option, even if its simply null. I use jQuery, so I can just use $.extend to merge the defaults and user-specified options like this: var opts = $.extend({}, defaults, opts);
I believe this is a great pattern. I've heard an options object like this referred to as a "builder object" in other languages (at least in the context of object creation). Here are some of the advantages:
Users of your function don't have to worry about what order the parameters are in. This is especially helpful in cases like yours where the method takes a lot of arguments. It's easy to get those mixed up, and JavaScript will not complain!
It's easy to make certain parameters optional (this comes in handy when writing a plugin or utility).
There are some pitfalls though. Specifically, the user of your function could not specify some of the options and your code would choke (note that this could also happen with a normal JS function: the user still doesn't have to supply the correct arguments). A good way for handling this is to provide default values for parameters that are not required:
var value = options.val || 0;
var element = options.ele || {};
$(element).val(value);
You could also return from the function immediately or throw an exception if the correct arguments aren't supplied.
A good resource for learning how to handle builder objects is to check out the source of things like jQueryUI.
I realize this question is a year old, but I think the cleanest way to pass an arbitrary number of arguments to a JavaScript function is using an array and the built in apply method:
fun.apply(object, [argsArray])
Where fun is the function, object is your scope/context in which you want the function to be executed and the argsArray is an array of the arguments (which can hold any number of arguments to be passed.
The current pitfall right now is that the arguments must be an array (literal or object) and not an array-like object such as {'arg' : 6, 'arg2' : "stuff"}. ECMAScript 5 will let you pass array-like objects, but it only seems to work in FireFox at the moment and not IE9 or Chrome.
If you look at the jQuery implementation, it uses an options class to handle most of the arbitrary-number-of-parameters functions, so I think you are in good company.
The other way is to test for arguments.length, but that only works if your arguments are always in the same order of optionality.
It's worth remembering that all functions have a bonus parameter called arguments that is an object very much like a JS array (it has length but none of the array functions) that contains all the parameters passed in.
Useful if you want to pass in a range of parameters (e.g.
function Sum() {
var i, sum = 0;
for (i=0; i < arguments.length; i++){
sum+=arguments[i];
}
return sum;
};
If this isn't the case and you just have a lot of parameters, use the params object as you've described.
Nothing wrong with that practice.
"Options" seems like as good a name as any.
You don't need to "unpack" them, but if you'll be accessing the same item several times, it will be a little more efficient to reference them in local variables because local variable access is generally quicker than property lookups.

Why is dynamically modifying a JavaScript function's code mid-execution a bad thing?

A few days ago, I asked a question regarding dynamically modifying a function's code midway through the outerlying script's execution and I was told to completely forget ever coming upon the notion. I'm not sure I understand why that is. Let me give an example:
<script>
var display = function(msg)
{
alert(msg);
}
// Now, at the moment, the display() function
// is receiving a single parameter and alerting
// it to the user. I'm now going to use eval()
// to modify the display() function.
eval('display = ' + display.toString().replace('alert(', 'document.write('));
// Now, the display() function writes its parameter
// to the document as opposed to alerting it.
</script>
I realize this is a rather trivial example, but there must surely be some use that can be derived from being able to dynamically modify a function, something so useful by itself.
Although this may do what you need it to do, 6 months from now you (or the person maintaining your code) will be going "WTF?!"
If your use case is to alert or write based on some condition, why don't you write two different functions? Or have your function take another parameter that decides the output mode. Or pass in a function as a parameter that performs the actual output. Something, you know, a little more on the sane side. ;-)
There are cases where it could be useful to change a function's behavior, but there are better ways to do it. In your example, you could create new instances of the function that handle the output differently, by passing a function as an argument (similar to the strategy pattern):
function makeDisplay(displayStrategy) {
return function(msg) {
// I'm assuming you would do some additional processing here...
displayStrategy(msg);
}
}
var display = makeDisplay(alert);
// now modify display to use document.write
display = makeDisplay(function(msg) { document.write(msg); });
Well, using eval might be a security concern but modifying a function in real-time is ok. How else you can make memoization anyway?
Although, come to think of it, changing method signature isn't a great idea, other people won't know how to call this function after this, since it would depend on execution order and it's not easy to track usually.
I have found myself needing to do this in situations where I don't have the source code for a particular piece of vendor javascript; so that could be a legitimate use case. I agree that if you have another option, it's better to do it in a more organised way, editing the original function to be more flexible.

Categories