You are not logged in.
Pages: 1
Hi, I'm trying to create a function that returns a dataset represented in JSON format...
I already have the function returning an array of strings (first field only), instead, I'll like to return a JSON object in its place.
FQuery.Open(vp.argv[0].asJSString.ToString(cx));
loop := 0;
obj := cx.NewRootedObject(cx.NewArrayObject(FQuery.RecordCount-1));
try
while not FQuery.eof do begin
obj.ptr.SetElement(cx, loop, SimpleVariantToJSval(cx, FQuery.Fields[0].AsString)); // add item to arr
inc(loop);
fQuery.Next;
end;
vp.rval := obj.ptr.ToJSValue;;
finally
cx.FreeRootedObject(obj);
end;
In this case, I'm receiving an array with the first field of the selection...
let arr = myfunction('select id,name from customers');
// this returns ['1','2','3','4']
However, I'll like to return something like
let arr = myfunction('select id,name from customers');
// to return returns [{id:'1',name:'Luis'},{id:'2',name:'peter'},{id:'3',name:'Rose'},{id:'4',name:'John'}]
I know I have to loop thru each field and get the field name, what I don't know how to do is to "wrap it" into an object...
FQuery.Open(vp.argv[0].asJSString.ToString(cx));
loop := 0;
obj := cx.NewRootedObject(cx.NewArrayObject(FQuery.RecordCount-1));
try
while not Fquery.eof do begin
// obj.ptr.SetElement(cx, loop, SimpleVariantToJSval(cx, FQuery.Fields[0].AsString)); // add item to arr
for fldCount := 0 to FQuery.FieldCount -1 do begin
fldName := FQuery.Fields[0].FieldName;
fldValue := FQuery.Fields[0].AsString;
// how to wrap it, and add it to the array? <---- Need help!
end;
inc(loop);
fQuery.Next;
end;
vp.rval := obj.ptr.ToJSValue;;
finally
cx.FreeRootedObject(obj);
end;
Thanks in advance,
Luis
Offline
In our application in the pascal code we serialize TSQLTable to JSON (string) using TSQLTable.GetJSONValues method and when JSON.parse the resulting string inside JavaScript. This is the simplest (and the fastest from our tests) way to solve your task.
Last edited by mpv (2018-11-14 07:48:40)
Offline
I wish I read your post before!!!! Thanks thou!
In the short run, and for future reference...
FQuery.Open(vp.argv[0].asJSString.ToString(cx));
loop := 0;
arr := cx.NewRootedObject(cx.NewArrayObject(FQuery.RecordCount-1));
try
while not Fquery.eof do begin
fld := cx.NewObject(nil);
for fldCount := 0 to FQuery.FieldCount -1 do begin
fldName := LowerCase(FQuery.Fields[fldCount].FieldName);
fldValue := FQuery.Fields[fldCount].AsString;
fld.SetProperty(cx, PAnsiChar(fldName), SimpleVariantToJSval(cx,fldValue)) ;
end;
arr.ptr.SetElement(cx, loop, fld.ToJSValue);
inc(loop);
fQuery.Next;
end;
vp.rval := arr.ptr.ToJSValue;
finally
cx.FreeRootedObject(arr);
end;
Offline
mrluis, this solution is risky
You must make fld rooted before using it
fld := cx.NewRootedObject(cx.NewObject(nil));
try
for fldCount := 0 to FQuery.FieldCount -1 do begin
fldName := LowerCase(FQuery.Fields[fldCount].FieldName);
fldValue := FQuery.Fields[fldCount].AsString;
fld.ptr.SetProperty(cx, PAnsiChar(fldName), SimpleVariantToJSval(cx,fldValue)) ;// <-------------you have chance to get AV here if garbage collector will start work
end;
arr.ptr.SetElement(cx, loop, fld.ptr.ToJSValue);
finally
cx.FreeRootedObject(fld );
end;
In opposite case garbage collector can move fld to another place in memory and you will get AV
Garbage collecting can start in any moment
Last edited by Orel (2018-11-16 13:14:17)
Offline
I was not sure if because is attached to a rooter, it should "inherit" from it... but you are right Orel! Thanks for the heads up!
Offline
Pages: 1