#1 2018-11-13 16:56:11

mrluis
Member
From: Florida
Registered: 2017-08-20
Posts: 24

How to return an array of JSON object...

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

#2 2018-11-14 07:47:48

mpv
Member
From: Ukraine
Registered: 2012-03-24
Posts: 1,074
Website

Re: How to return an array of JSON object...

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

#3 2018-11-14 19:34:10

mrluis
Member
From: Florida
Registered: 2017-08-20
Posts: 24

Re: How to return an array of JSON object...

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

#4 2018-11-16 13:13:09

Orel
Member
Registered: 2014-04-14
Posts: 11

Re: How to return an array of JSON object...

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

#5 2018-12-01 18:59:41

mrluis
Member
From: Florida
Registered: 2017-08-20
Posts: 24

Re: How to return an array of JSON object...

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

Board footer

Powered by FluxBB