using the following constructor in the parse function throws an exception:
new Function("args", body);
"Uncaught SyntaxError: Unexpected identifierkendo.data.DataSource.schema.parse @ KendoWorklist?processId=1:257g.extend.success @ kendo?v=eOyB53xLlSdFHOrBbggvVxenL4FmfrA-viibHS3DbGs1:1g.extend.read.i._queueRequest.i.online.i.transport.read.success @ kendo?v=eOyB53xLlSdFHOrBbggvVxenL4FmfrA-viibHS3DbGs1:1vt.extend.read.i.success @ kendo?v=eOyB53xLlSdFHOrBbggvVxenL4FmfrA-viibHS3DbGs1:1i.Callbacks.a @ jquery?v=FVs3ACwOLIVInrAl5sdzR2jrCDmVOWFbZMY6g6Q0ulE1:1i.Callbacks.h.fireWith @ jquery?v=FVs3ACwOLIVInrAl5sdzR2jrCDmVOWFbZMY6g6Q0ulE1:1k @ jquery?v=FVs3ACwOLIVInrAl5sdzR2jrCDmVOWFbZMY6g6Q0ulE1:1i.ajaxTransport.send.u @ jquery?v=FVs3ACwOLIVInrAl5sdzR2jrCDmVOWFbZMY6g6Q0ulE1:1"
why would the new Function constructor not work in the parse function?
5 Answers, 1 is accepted

the reason I want to use the new Function() constructor is because I send my data over normalized and the most efficient way to denormalize it is as follows:
// My starting Normalized data
var
fields = [
"name"
,
"age"
];
var
data2 = [[
"John"
,20],[
"Tom"
,25]];
// What I want the result to look like Denormalized
var
data1 = [{
"name"
:
"John"
,
"age"
:20},{
"name"
:
"Tom"
,
"age"
:25}];
// Solution 1 O(N^2) --- this is slow
var
fields = [
"name"
,
"age"
];
var
data2 = [[
"John"
,20],[
"Tom"
,25]];
var
data1 = [];
for
(
var
i = 0; i < data2.length; i++){
var
temp = {};
for
(
var
y = 0; y < fields.length; y++){
temp[fields[y]] = data2[i][y];
}
data1.push(temp);
}
// solution 2 O(N)
var
fields = [
"name"
,
"age"
];
var
data2 = [[
"John"
,20],[
"Tom"
,25]];
var
body =
""
;
for
(
var
i = 0; i < fields.length; i++){
body +=
"this."
+fields[i] +
"=args["
+i+
"]; "
;
}
var
model =
new
Function(
"args"
,body);
var
data1 = [];
for
(
var
i = 0; i < data2.length; i++){
var
x =
new
model(data2[i]);
data1.push(x);
}
I think both solutions have the same complexity O(N*M);
Where N is the count of the data.
And M is the count of the fields.
Additionally the const of the both approaches is pretty much the same.
The difference is that in first approach you iterate the properties and build the object yourself. And in the second approach you pass some big constructor for this object, and the JS engine parses the values and then the browser do the same: iterate them and build the object.
If you perform some test, you will get very similar times in both large and small set of data. Here is some code based on yours:
var
fields = [];
var
data2 = [];
for
(
var
j = 0 ; j < 1000; j++) {
fields.push(
"a"
+ j +
"r"
+ Math.floor(Math.random() * 100));
}
for
(
var
i = 0; i < 10000 ; i++) {
var
item = [];
for
(
var
j = 0 ; j < 100; j++) {
item.push(Math.random());
}
data2.push(item);
}
var
data1;
function
f1() {
data1 = [];
data1.length = data2.length;
var
temp;
for
(
var
i = 0; i < data2.length; i++) {
temp = {};
for
(
var
y = 0; y < fields.length; y++) {
temp[fields[y]] = data2[i][y];
}
data1.push(temp);
}
};
function
f2() {
var
body =
""
;
for
(
var
i = 0; i < fields.length; i++) {
body +=
"this."
+ fields[i] +
"=args["
+ i +
"]; "
;
}
var
model =
new
Function(
"args"
, body);
data1 = [];
data1.length = data2.length;
for
(
var
i = 0; i < data2.length; i++) {
var
x =
new
model(data2[i]);
data1.push(x);
}
};
The times that I get are 2.478s for the first function and 2.264 for the second for this very big set of data. For small set of data they work practically the same.
From profiling in chrome it seems that the difference comes mainly from execution of the garbage collector more often in the first function.
So you can use the working approach without any worries. I will additionally debug why the second one fails when passed as a parse function.
Regards,
Vasil
Telerik


also instead of concatenating with "+=" I should've used ".concat()"
with this change f2() is much master than f1()
Interesting is that in Firefox (Nightly Builds) the solution 2 is actually slower than solution 1.
Back to the original subject. I tried to get the same error as you, but in my case it is working correct, even with your original code.
Here is testing example in our dojo:
http://dojo.telerik.com/egIsA
When I run it I get the alert displaying the name and age of the first record. And looking at the console, there is no exception like described.
What I see here as the potential problem if the fields contains numbers without literal prefix.
For example if the field is called "123" instead of "name". Then you will get exception when evaluating function like:
"this.123 = something".
however the first solution will work:
this[123] = something
Could you check the example code above, and tell me what is different in your case. You can edit the example and write here the new link you get.
Regards,
Vasil
Telerik