How to convert object value to function in javascript? - javascript

I want to used objects to store function name and another properties which i will used it to load jS script by Jquery getScript.
I have used conditional by inAarray to check if an object is existing in this array I will call that scrip and execute that function (func) but I still have stack to convert that object value to a function for execution after JS scrip load within status success.
function fetchingData(n_source_id, types, not_id) {
var data = {
'Loan Repayment':{
url:'/js/load/loan/loan_repayment.js',
func:'repayment'// name of function which I will call after JS file successfully loaded
},
'Reject Repayment':{
url:'/js/load/loan/repay_change_till_acc.js',
func:'changeTill'// name of function which I will call after JS file successfully loaded
},
'Issue Till': {
url: '/js/load/issueTill.js',
func: 'issueTill'// name of function which I will call after JS file successfully loaded
}
};
$.each(data, function(inx, vals) {
var _type = inx;
var url = vals;
if ($.inArray(types, [_type]) >= 0) {
ScriptRequire([vals.url], function(status) {
if (status === 'success') {
var fun = new Function(vals.function);
console.log(fun(n_source_id, types));
return fun;
}
});
}
});
}

Since vals.function holds the name of the function, and the function should already be defined by the loaded script, do not use the following to get the function object:
var fun = new Function(vals.function);
Instead, use:
var fun = window[vals.function];

Related

Object modified in the function is not being modified outside the function

I'm building a code to parse some JSON details received from the server into a javascript object. The object has many objects inside it.
Then I have another function to create HTML element and apply that object's values (using for - in loop) into HTML tags' "innerHTML".
I have included the code i use below,
// This one is executed on the 'onLoad' event.
function requestDriverListings() {
**//This object stores the received object from server.**
var drivers = {};
// ***This function requests details from the server and the function in the arguments is executed once the details are received.***
sendUserData ({}, "request driver.php", function (request) {
listDrivers(request,drivers); console.log(drivers); displayDrivers(drivers);});
}
This one is the function to create a HTML Element and stores the received data in it and the use JSON.parse() to parse them into a Object.
The driver parameter is the Object passed in the above code.
request parameter has no effect on this problem. (It is the XHR responseText.)
function listDrivers (request,driver) {
var response = document.createElement("html");
response.innerHTML = request;
driver = response.querySelector("#drivers").innerHTML;
var stripComma = driver.lastIndexOf(",");
driver = JSON.parse(driver.substring(0,stripComma) +"}");
}
Here is the displayDrivers function.
drivers Object is passed into driveParsed in the first function.
requestAPage() is a function to request the displaying element from the server. the function in it's arguments is the function to apply the Objects details into the HTML innerHTML.
function displayDrivers (driveParsed) {
var driverElement = document.createElement("div");
driverElement.id = "driverElement";
driverElement.style.display = "none";
document.getElementById("driverContainer").appendChild(driverElement);
requestAPage("Drivers.html", "drivers", "driverElement", function() { selectDrivers();});
var selectDrivers = function () {
for (var x=0; x<=Object.keys(driveParsed).length; x++) {
var driverParsed = driveParsed[x];
setDriversDetails(driveParsed,x);
var element = createAElement( "div", {"margin-top": "10px;"});
element.id = driveParsed.name;
element.className = "container border";
element.innerHTML = driverElement.innerHTML;
document.getElementById("driverContainer").appendChild(element);
}
};
}
================================================================
My problem is this displayDrivers() is not getting the modified drivers Object.
Please help me to solve this problem. Sorry for the long description.
One problem is that inside listDrivers you assign a new value to the driver variable (which is an argument). This means the original variable, drivers, that was passed to the function as second argument, is disconnected from the local function variable driver: they are now two distinct, unrelated objects.
If you want the drivers variable to get a value from calling the function, then let that be the return value of the function, so you would call it like this:
sendUserData ({}, "request driver.php", function (request) {
var drivers = listDrivers(request); // <-----
console.log(drivers);
displayDrivers(drivers);
});
Then the listDrivers function would look like this:
function listDrivers (request) { // <--- only one argument
// declare new variable:
var driver = response.querySelector("#drivers").innerHTML;
// ... rest of your code comes here ...
// ... and finally:
return driver; // <---- return it
}
#trincot beat me to it and his answer is better. I'll leave this up anyway though.
Try doing this in requestDriverListings:
function requestDriverListings() {
var drivers = {};
sendUserData ({}, "request driver.php", function (request) {
var updatedDrivers = listDrivers(request,drivers);
console.log(drivers);
displayDrivers(updatedDrivers);});
}
And this in listDrivers:
function listDrivers (request,driver) {
var response = document.createElement("html");
response.innerHTML = request;
driver = response.querySelector("#drivers").innerHTML;
var stripComma = driver.lastIndexOf(",");
driver = JSON.parse(driver.substring(0,stripComma) +"}");
return driver;
}

How to assign existing function to object (not call it immediately) by it's name as a String from JSON file?

I would like some help assigning function to object. I have JSON file containing function names (as string ofc...) and in my code I have already existing functions. I don't want this functions to be called just assigned so I can call them later.
I also want to be able to pass a custom function as a string from JSON file. I tried to parse it but I get Unexpected token m...
operations.push --> run: is where I want to assign function.
This is my code with what I have tried so far:
async function operate(schemaObject) {
let operations = [];
for (let operation in schemaObject.operate) {
if(schemaObject.operate.hasOwnProperty(operation)) {
//Function name as a string ex: "matchIntegerOrUnlimited"
let functionName = schemaObject.operate[operation].action;
//Function parameter (val) ex: "test 123"
let functionParam = schemaObject.operate[operation].parameter;
//Custom Function ex: "return alert(Hello)
if (operation.custom) {
operations.push({
run: new Function("test 123", return alert("123"),
on: schemaObject.operate[operation].key
});
} else {
//Push existing Function matchIntegerOrUnlimited()
operations.push({
run: functionName, //"matchIntegerOrUnlimited"
on: schemaObject.operate[operation].key
});
}
}
}
console.log(operations);
return operations;
}
function matchIntegerOrUnlimited(val) {
if (contains(val, unlimitedPattern)) {
return 10000;
} else {
let number = val.match(numberPattern)[0];
return parseInt(number, 10);
}
}
So I expect to be able to just assign function that can be called later by giving a existing function name as Sting... and also if possible to give a custom function as a String

JavaScript Object is set but is null when accessed

I have the following object that constructs a session variable:
var sessionObject = function (key) {
this._key = key;
this._content;
this.set = function (v) {
this.setLocal(v);
$.post('/Program/SetVariable',
{ key: this._key, value: v }, function (data) {
});
};
this.get = function (callback) {
var setterCallback = this.setLocal;
$.get('/Program/GetVariable',
{ key: this._key }, function (data) {
setterCallback(data);
}).done(function () {
callback();
});
};
this.setLocal = function (v) {
this._content = v;
};
this.getLocal = function () {
return this._content;
};
}
And my C# in the controller is as follows:
public ActionResult SetVariable(string key, string value)
{
Session[key] = value;
return this.Json(new { success = true });
}
public ActionResult GetVariable(string key)
{
return this.Json(Session[key], JsonRequestBehavior.AllowGet);
}
I create a new session object every time the page is loaded, which references items in the session located on the server. When the session is set with the set() function, _content is set correctly and is able to be accessed publicly through item.getLocal() (either in the browser console or in code).
When I revisit the page and the session object referring to said item is already created, when I run the item.get() function it accesses the session variable and sets it to the _content object, I know this because I can do a console.log(this._content) in the setLocal() function which shows that the variable has been set correctly. But when I wish to access the content of the session object via either this.getLocal() or item._content while through the browser console or other lines of the code I get undefined returned to me.
So to illuminate the process some more this is what I do on a reload where there is already data in the session:
var item = new sessionObject("item");
item.get(printData);
function printData() {
$("printbox").append(item.getLocal());
}
This does not print anything.
Is there a reason I can not access this item's content unless it is specifically set by the item.set function?
Because you do this:
var setterCallback = this.setLocal;
and call it like so:
setterCallback(data);
You have lost the context of your sessionObject instance, so the this inside the setLocal function is no longer your object instance but the global window object.
You can do two things to correct this, save a reference to this instead of saving a reference to the function and call setLocal from that reference
var that = this;
/.../
that.setLocal(data);
or you can bind object instance when you save the setLocal reference
var setterCallack = this.setLocal.bind(this);

JavaScript OOP : running two instances of a method within a single Object simultaneously

So, I have an object Async that creates a request for (in this case) a JSON object from github.
There is a method Async.createList that creates a list of all instances of a specific attribute from the github JSON object. It works just fine when Async.createList is called once, but I want to be able to create multiple lists from different target attributes from the same request, and this is where it fails.
Ideally, the lists would be appended to the Async.lists object so that they can be used outside of the Async object. Right now, when I call Async.createList multiple times, only the last call appends to Async.lists.
function Async(address) {
this.req = new XMLHttpRequest();
this.address = address
}
Async.prototype = {
lists : {},
create : function(callback) {
var self = this;
this.req.open('GET', this.address, true);
this.req.onreadystatechange = function(e) {
if (this.readyState == 4) {
if (this.status == 200) {
dump(this.responseText);
if (callback != null) callback()
} else {
dump("COULD NOT LOAD \n");
}
}
}
this.req.send(null);
},
response : function(json) {
return json == true ? JSON.parse(this.req.responseText) : this.req.responseText
},
createList : function(target) {
var self = this
var bits = []
this.req.onload = function(){
var list = self.response(true)
for(obj in list){
bits.push(self.response(true)[obj][target])
}
self.lists[target] = bits
}
},
}
I am creating the object and calling the methods like this:
var github = new Async("https://api.github.com/users/john/repos")
github.create();
github.createList("name");
github.createList("id");
And then trying:
github.lists
You are re-assigning the function for this.req.onload every time you call github.createList.
i understand you want to do things after the request is loaded using req.onload, but you are assigning a new function everytime, so the last assigned function will be called.
You need to remove the onload function within Async.createList
Call github.createList("name"); only after the request is loaded as follows
var github = new Async("https://api.github.com/users/john/repos")
github.create();
github.req.onload = function () {
github.createList("name");
github.createList("id");
}
The answer is painfully simple. All I needed to do was get rid of the onload function within Async.createList and simple call Async.createList in the callback of Async.create
createList : function(target) {
var self = this
var bits = []
var list = self.response(true)
for(obj in list){
bits.push(self.response(true)[obj][target])
}
self.lists[target] = bits
},
Using this to instantiate:
var github = new Async("https://api.github.com/users/john/repos")
github.create(callback);
function callback(){
github.createList("name");
github.createList("id");
}

run javascript function from string variable and pass parameters

I need to call a user defined javascript function from within my costom jquery plugin and pass parameters to it, for example:
function test(data)
{
var myfunc="function(data){alert(data);}"; //this is user defined function I retrieved from html tag attribute
var fn=new Function("("+myfunc+")();");
fn.apply(this,arguments);
return fn;
}
test("hello");
The result is undefined, how can I pass data parameter from test function to user defined function? thanks in advance!
question update:
I'm writing a jquery plugin to handle ajax request, much like asp.net mvc unobtrusive ajax, I get the ajax callfack function from html tag attrbute, for example:
<div data-ajax-success="function(data,status,xhr){alert(data);}"....
the value of data-ajax-success attribute is user defined function, it can be following formats:
data-ajax-success="function(data,status,xhr){alert(data);}"
data-ajax-success="function(data){alert(data);}"
data-ajax-success="function(){alert('hello');}"
data-ajax-success="functionName"
I need to parse this attribute value as javascript function and pass jquery ajax callback parameters to this function, where data-ajax-success value is function name, I could call it correctly using following method defined in Micrsoft jquery-unobtrusive-ajax.js:
function getFunction(code, argNames) {
var fn = window, parts = (code || "").split(".");
while (fn && parts.length) {
fn = fn[parts.shift()];
}
if (typeof (fn) === "function") {
return fn;
}
argNames.push(code);
return Function.constructor.apply(null, argNames);
}
but when data-ajax-success is function body, I could not pass parameter to it, here's my sample code that handle ajax callback:
loadData: function (index, options) {
complete: function (xhr,status) {
$(context.loading).hide(context.loadingDuration);
getFunction(context.onComplete, ["xhr", "status"]).apply(this, arguments);
},
success:function (data, status, xhr) {
$(context.updateTarget).html(data);
getFunction(context.onSuccess, ["data", "status", "xhr"]).apply(this, arguments);
},
error: getFunction(context.onFailure, ["xhr", "status", "error"])
});
$.ajax(options);
}
anyone can help me? thank you very much!
MDN describes the syntax of the Function object like this:
new Function ([arg1[, arg2[, ... argN]],] functionBody)
Here is the corresponding example:
// Example can be run directly in your JavaScript console
// Create a function that takes two arguments and returns the sum of those arguments
var adder = new Function("a", "b", "return a + b");
// Call the function
adder(2, 6);
// > 8
Applied to your example code it should read:
var fn=new Function("data",myfunc);
Reference:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function
You are not passing an argument to the fn function.
Change this part:
var fn=new Function("("+myfunc+")();");
to this:
var fn=new Function("("+myfunc+")("+data+");");
But if you are defining the function like that the data variable must contain a json string:
var fn=new Function("("+myfunc+")("+JSON.stringify(data)+");");
I think you are not correctly using the Function constructor. See this link for reference:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function?redirectlocale=en-US&redirectslug=Core_JavaScript_1.5_Reference%2FObjects%2FFunction#Example.3A_Specifying_arguments_with_the_Function_constructor
Please check this
<!DOCTYPE html>
<html>
<body>
<p>Setting a default value to a function parameter.</p>
<p id="demo"></p>
<script>
function test(content)
{
const funString = `(function(content){return content})(content)`
var adder = eval(funString);
// Call the function
return adder;
}
document.getElementById("demo").innerHTML = test(2);
</script>
</body>
</html>
I solved it by modifying this microsoft method:
function getFunction(code, argNames) {
var fn = window, parts = (code || "").split(".");
while (fn && parts.length) { fn = fn[parts.shift()]; }
if (typeof (fn) === "function") { return fn; } //onSuccess="functionName"
if ($.trim(code).toLowerCase().indexOf("function")==0) { return new Function("return (" + code + ").apply(this,arguments);");} //onSuccess="function(data){alert(data);}"
argNames.push(code);
try {return Function.constructor.apply(null, argNames); //onSuccess="alert('hello');return false;"
}catch(e){alert("Error:\r\n"+code + "\r\nis not a valid callback function");}
}

Categories