AngularJS invoking function whose name is constructed as a string - javascript

I have a situation in which there are main functions named as:
Add_<Element_Type>_Page()
where Element_Type is received as a parameter.
I can see two options to handle the invocation of the correct function:
Write a relatively long switch construct covering all possible values of Element_Type, or
Use some existing mechanism/trick (I'm not aware of) through which I can build a string using the received Element_Type and invoke a function whose name is contained in that string.
Needless to say, all the functions that can be invoked this way have exactly the same signature as far as parameters is concerned.
Obviously, Option 2 would be the best (easy to maintain and very general as no changes are needed whenever a new type of pages is added).
Is this possible to achieve within AngularJS framework?
Thanks in advance.

You can simply do that using the [...] notation instead of .
Like this,
$scope["Add_" + Element_Type + "_Page"]()
will call $scope.Add_test_Page() assuming Element_Type would be test
or if using controllerAs syntax,
vm["Add_" + Element_Type + "_Page"]()
where Element_Type is a received parameter as you mentioned.
If you want to use it inside HTML, you can have a reference to your Element_Type in $scope/vm (whichever way you are using) and access it.

Create an attribute with name func-name and pass your dynamic string value which is your function name to that attribute and within your directive you can do something like this.
scope: {
funcName: '#'
},
controller: function() {
$scope[$scope.funcName]();
}

Related

Passing object as a parameter in a template literal in javascript

I currently have an object which I want to pass as a parameter to another function inside a template literal:
var template = `<button onclick="onclick(${object})"></button>`;
However, this makes the parameter become a string value: [object Object] and doesn't pass the parameter. Is there any way to pass this parameter into the function?
Thank you very much in advance.
You are going to need to represent your object as a string. You can do this using JSON.stringify:
var template = `<button onclick="handleClick(${JSON.stringify(obj).split('"').join(""")})"></button>`;
You will need to escape double quotes (which this code does), and single quotes if used for your onclick event (this code doesn't).
onclick="onclick" actually calls window.onclick - meaning that it picks up clicks anywhere. You should use a different name (such as handleClick).
I would suggest refraining from using inline event listeners for reasons like this, and because they can cause issues if you ever need to adopt a content-security-policy.

Haxe Javascript: Prevent '$bind' generation?

Is there a simple way to prevent $bind generation when passing around class member functions?
I have an object that takes in a function which will be called in an arbitrary interval. The object always binds itself as the 'this' binding before calling the function (this is done in the native side), therefore the call to $bind itself is unnecessary. However, I can't seem to find a simple way to prevent $bind from being emitted any time I grab a member function by value.
The only way I've found is to use __js__ with a string literal of the member function name, which I would rather avoid... Is there a typed way to do so? Or something a bit nicer? A way to still use haxe syntax w/ identifiers instead of a string literal?
Example:
private function onSpawn():Void
{
this.setAct( act ); // Will generate JS: this.setAct($bind(this,this.act));
// Id like to simply have it generate: this.setAct( this.act );
// Mitigated like this:
this.setAct( untyped __js__("this.act") );
}
private function act( dt:Float ):Void
{
...
}
Thank you.
You use macro to mask out the untyped expression, but this is quite dangerous.
Any reference to "this" will fail.
http://try-haxe.mrcdk.com/#70ee4
Btw, I think the compiler may be optimized to not generate $bind if the function code doesn't involve "this". You may want to raise an issue in the github repo about that.

How can I generate a unique JavaScript variable name from a JSF clientId?

I want to define a JavaScript function for every instance of a JSF composite component.
For this, inside the component, I'm trying something like:
<h:outputScript>
function myFunction_#{component.clientId}(day) {
//do my instance specific stuff
}
</h:outputScript>
Specifically I am trying to use this function in a RichFaces calendar like this:
<rich:calendar id="calendar" ... dayClassFunction="myFunction_#{component.clientId}">
But the clientId doesn't necessarily only contain characters which are valid in JavaScript variable names.
Is there a way to calculate an md5 hash or something similarly pseudo-unique from the clientId (or something else!) inside a JSF EL expression?
I need it instance-specific because the return value relies on the instance values and the dayClassFunction attribute doesn't accept a function that takes the clientId itself or something likewise specific as an argument.
I've done it before like this:
window['#{cc.clientId}'] = {
myFunction1 : function() { ... },
myFunction2 : function() { ... }
};
then simply call it where you need it with
dayClassFunction="window['#{cc.clientId}'].myFunction1()"
This way everything is scoped to your component. Eventually you can add some prefix to the client id to never get into conflict with other variable names on the window scope.
Can't think of any character, which is allowed in a client id, that would break the javascript.
Assuming it's the separator (:) that's the issue you could use fn:replace:
function myFunction_#{fn:replace(component.clientId, ':', '_')}
When calling your function, JSF will assign this to be the instance-specific JS object which JSF uses to implement the client side. You may be able to get the information you need from that.

How to pass multiple params into a delegate in Javascript?

I have the following JS code, which uses jQuery:
var anArray=[];
var passIntoFun =100; // calculated value;
function ArrayIteratorFun(index, element, thirdParam){
// function code.
}
I want to call ArrayIteratorFun using .each construct, like:
$(anArray).each(ArrayIteratorFun(passIntoFun));
I could only call it like, by wrapping into a function:
$(anArray).each(function(i,e){ArrayIteratorFun(i,e,passIntoFun);});
is there any better way to write the code above?
Assuming your example is oversimplified and your function does not have access to the variable you wish to pass in as an argument (as one comment alludes to)...
The problem you have is that of pre-filling certain arguments (thirdParam in your case) of your ArrayIteratorFun. Sometimes you'll see this kind of technique called partial application or currying.
You happen to want to apply the third argument (leaving the preceding ones unfilled), which removes the possibility of using Function.prototype.bind. Bind is useful, but I often use the more flexible partial function from underscore.
With partial you can apply arbitrary arguments, by using _ in place of arguments that you want to apply/fill later:
$(anArray).each(_.partial(ArrayIteratorFun, _, _, passIntoFun));
The above ignores the first 2 arguments of ArrayIteratorFun (using underscores) and applies the value of passIntoFun to the third argument.
EDIT: I'm not aware of any way that jQuery provides of doing the same thing as _.partial. However if you are restricted to not using underscore (or a similar framework) then I recommend you check out the implementation of partial in underscore and this great article on the subject of partial application in javascript. These both provide ways of implementing using only plain javascript.

Shortcut for accessing object attributes in javascript

I have a model object with a property called definition that i am using across a class. I can access that property like model.attributes.definition
Every time that i want to use this property inside a method, and for the sake of clarity, i am creating a shortcut definition = model.attributes.definition at the very beggining so the method code does not get populated with boilerplate.
Because i am using it across several methods i thought that, instead of creating the shortcut on every method, i could create a little helper function to do the job:
getDefinition: (model) ->
model.attributes.definition
and then use it anywhere like
if getDefinition(model).name?
doSomething()
But aren't these function calls across my code innecessary/resource consuming for such a trivial task? What is a good approach in a situation like this?
You can also access object values via string:
definition = "attributes.definition"
then to access the value:
if model[definition].name?
doSomething()

Categories

Resources