Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 10 of 12 total
Thread Sending multiple records using a TServerRequest
Tue, Sep 17 2019 6:09 AMPermanent Link

Paul Coshott

Avatar

Hi everyone,

I use the TServerRequest component to move data to and from the server quite a bit in my app. But I've only ever done it for a single record.

Can anyone tell me how I code things in EWB so I can send multiple records, and then what i have to do in Delphi to retrieve the multiple records using TEWBModule, so I can then do what I need with the data.

Hopefully this is possible with EWB.

Cheers,
Paul
Wed, Sep 18 2019 6:06 AMPermanent Link

Matthew Jones

Paul Coshott wrote:

> I use the TServerRequest component to move data to and from the server quite a bit in my app. But I've only ever done it for a single record.
>
> Can anyone tell me how I code things in EWB so I can send multiple records, and then what i have to do in Delphi to retrieve the multiple records using TEWBModule, so I can then do what I need with the data.

Depending on what exactly you are sending to, you can just have either multiple TServerRequests, or use TServerRequestQueue to manage them for you. And if that isn't quite right, it isn't hard to make your own manager.

Fundamentally, each TServerRequest is independent, so you can do what you want, and create them dynamically or have a set number on the form for each task. They are asynchronous of course, so unless you manage them, they may return in a different order etc.

--

Matthew Jones
Wed, Sep 18 2019 9:33 PMPermanent Link

Paul Coshott

Avatar

Hi Matthew,

Thanks for the answer. I didn't explain what I am trying to do clearly enough. I don't need to send multiple server requests, just multiple records from the same dataset (with one server request call).

For example, if I had a web shop order and I needed to send the order detail lines to the server. If I had 6 products purchased on the order, how do I send the 6 records to the server? In TMS's XData, I would use a JSON Object to represent the product line, and I'd add 6 of these to a JSON Array and then simply pass the array.

I was thinking I could possibly use a TPersistant class to create the record, and then add them to a TObjectList, but I don't know how to pass a TObjectList via a TServerRequest.

The following may not be the way to do this. If not, how should I do it?

I was trying something like:

type
 TOrderLines = class(TPersistent)
 private
   FOrderNo: Integer;
   FProduct: String;
   FQuantity: Integer;
 published
   property OrderNo: Integer read FOrderNo write FOrderNo;
   property Product: String read FProduct write FProduct;
   property Quantity: Integer read FQuantity write FQuantity;
 end;

In the forms OnCreate event:
 OrderLines := TOrderLines.Create;

Then fill the TOrderLines by looping around a TDataSet to get the data.

 objOrder := TObjectList.Create;
 try
   OrderLines.OrderNo := 1;
   OrderLines.Product := 'ABC-123';
   OrderLines.Quantity := 3;
   objOrder.Add(OrderLines);

   //... add more OrderLines to the TObjectList objOrder

   with svrreqOrder do begin
     Method := rmPost;
     Params.Values['user'] := authUN;
     Params.Values['password'] := authPW;
     URL := '/modules/tp_daWebShopSave';
     RequestHeaders.Clear;
     RequestHeaders.Values['Content-Type'] := 'text/plain';
     RequestContent.Clear;
     RequestContent.Values['tpService'] := 'Save_Order';
     RequestContent.Values['SomeId'] := IntToStr(gblSomeId);
     RequestContent.Values['EventData'] := objTest;                    <---- COMPILE FAILS HERE
     Execute;
   end;

 finally
   objOrder.Free;
 end;

 
Thanks,
Paul
Thu, Sep 19 2019 4:30 AMPermanent Link

Matthew Jones

Paul Coshott wrote:

> For example, if I had a web shop order and I needed to send the order detail lines to the server. If I had 6 products purchased on the order, how do I send the 6 records to the server? In TMS's XData, I would use a JSON Object to represent the product line, and I'd add 6 of these to a JSON Array and then simply pass the array.
>
> I was thinking I could possibly use a TPersistant class to create the record, and then add them to a TObjectList, but I don't know how to pass a TObjectList via a TServerRequest.



Yes, that's what you need to do - assuming that you are not using the EWB "native" database code (I didn't in my shop). You can get a "manual" JSON creation of arrays and the like.

TDayRepeatDto = class(TPersistent)
published
 property SomethingToStream : blah;
end;


function TDayRepeatDto.GetJSON : String;
var               
   xWriter : TWriter;
begin
   xWriter := TWriter.Create(dtfISO8601);
   try
   xWriter.Initialize;

   Save(xWriter);

   Result := xWriter.Output;
   finally
       xWriter.Free;
   end;
end;

See how that goes for you - there are probably examples in the forums if you search for TWriter too. I have more complex code for lists, but better for you to find a problem and ask than me to confuse you with stuff I don't understand any more. Look at LoadProperty and LoadArrayElement if you are reloading, and if you get fancy with multiple lists, that's possible too.
--

Matthew Jones
Thu, Sep 19 2019 4:52 AMPermanent Link

Walter Matte

Tactical Business Corporation

Paul:

I don't know how you are going to convert a TObjectList to Text.  Which is probably what the compiler error is referring to.

You already have TDataset - no need to loop - user Method GetRows.

If you have made object from TDataset   "OrderLines"  set the global Database.AutoTransactions := false; so that usage of the TDataset does not auto commit back to the server. then you can use  OrderLines.GetRows to get a JSON string.


     RequestContent.Values['EventData'] := encodeURIComponent(  OrderLines.GetRows );


Walter


Paul Coshott wrote:


Hi Matthew,

Thanks for the answer. I didn't explain what I am trying to do clearly enough. I don't need to send multiple server requests, just multiple records from the same dataset (with one server request call).

For example, if I had a web shop order and I needed to send the order detail lines to the server. If I had 6 products purchased on the order, how do I send the 6 records to the server? In TMS's XData, I would use a JSON Object to represent the product line, and I'd add 6 of these to a JSON Array and then simply pass the array.

I was thinking I could possibly use a TPersistant class to create the record, and then add them to a TObjectList, but I don't know how to pass a TObjectList via a TServerRequest.

The following may not be the way to do this. If not, how should I do it?

I was trying something like:

type
 TOrderLines = class(TPersistent)
 private
   FOrderNo: Integer;
   FProduct: String;
   FQuantity: Integer;
 published
   property OrderNo: Integer read FOrderNo write FOrderNo;
   property Product: String read FProduct write FProduct;
   property Quantity: Integer read FQuantity write FQuantity;
 end;

In the forms OnCreate event:
 OrderLines := TOrderLines.Create;

Then fill the TOrderLines by looping around a TDataSet to get the data.

 objOrder := TObjectList.Create;
 try
   OrderLines.OrderNo := 1;
   OrderLines.Product := 'ABC-123';
   OrderLines.Quantity := 3;
   objOrder.Add(OrderLines);

   //... add more OrderLines to the TObjectList objOrder

   with svrreqOrder do begin
     Method := rmPost;
     Params.Values['user'] := authUN;
     Params.Values['password'] := authPW;
     URL := '/modules/tp_daWebShopSave';
     RequestHeaders.Clear;
     RequestHeaders.Values['Content-Type'] := 'text/plain';
     RequestContent.Clear;
     RequestContent.Values['tpService'] := 'Save_Order';
     RequestContent.Values['SomeId'] := IntToStr(gblSomeId);
     RequestContent.Values['EventData'] := objTest;                    <---- COMPILE FAILS HERE
     Execute;
   end;

 finally
   objOrder.Free;
 end;

 
Thanks,
Paul
Thu, Sep 19 2019 6:39 AMPermanent Link

Paul Coshott

Avatar

Hi Guys,

Thanks so much for the help. As I am using a TDataSet, I think Walter's suggestion sounds like a good method to try.

Could you show me a bit of code to use in the Delphi side, to read the rows and columns of data. The following is what I would normally do. What do I need to change to read the multiple rows.

Thanks again for all the help. Really appreciate it.

Cheers,
Paul


     if (RequestMethod = rmPost) then begin
       TempResult:=False;
       TempContent := TStringList.Create;
       try
         TempContent.Text := UTF8ToWideString(RequestContent);

         //save the passed staff details

         sErrorMsg := 'An error occured while trying to save the staff details.';
         TempStaffId := StrToInt(TempContent.Values['StaffId']);
         TempCompanyID := StrToInt(TempContent.Values['CompanyId']);
         TempFirst := TempContent.Values['FirstName'];
         TempSurname := TempContent.Values['Surname'];
         TempDisplay := TempContent.Values['Display'];
Thu, Sep 19 2019 6:57 AMPermanent Link

Paul Coshott

Avatar

Hi Walter,

My EWB project fails when compiling on the

RequestContent.Values['EventData'] := encodeURIComponent(dsEvent.GetRows);

[Error] EventMnt.wbs (299,47): There is no function or procedure declaration that matches the encodeURIComponent(dsEvent.GetRows()) reference

Where do I find the encodeURIComponent function ?

Thanks,
Paul
Thu, Sep 19 2019 7:11 AMPermanent Link

Paul Coshott

Avatar

Hi Walter,

>>My EWB project fails when compiling on the

>>RequestContent.Values['EventData'] := encodeURIComponent(dsEvent.GetRows);

>>[Error] EventMnt.wbs (299,47): There is no function or procedure declaration that matches the >>encodeURIComponent(dsEvent.GetRows()) reference

I found the file I needed to include - WebDom.

Thanks,
Paul
Thu, Sep 19 2019 8:51 AMPermanent Link

Walter Matte

Tactical Business Corporation

Yup WebDom.

On the delphi side you will need to get the EventData and you will need to put the string returned from EventData through URI_Decode.

Delphi:

Uses  system.netencoding

sJSONEventData := TNetEncoding.URL.Decode( sEvendData );

Use a JSON parser to get at the sJSONEventData.
Thu, Sep 19 2019 8:51 AMPermanent Link

Matthew Jones

Paul Coshott wrote:

> As I am using a TDataSet, I think Walter's suggestion sounds like a good method to try.

Certainly does - myself, I've tried not to use the built in data sets, so I retain complete control, but my servers are typically not straightforward. All good options though.

--

Matthew Jones
Page 1 of 2Next Page »
Jump to Page:  1 2
Image