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