Web forum is in read-only mode. Login as active registered customer for write access
  Forum Search   New Posts New Posts

TXDataWebDataSet and picture

 Post Reply Post Reply
Author
Dino Gomezel View Drop Down
Member
Member
Avatar

Joined: 27 Aug 2018
Posts: 88
Post Options Post Options   Quote Dino Gomezel Quote  Post ReplyReply Direct Link To This Post Topic: TXDataWebDataSet and picture
    Posted: 27 Sep 2019 at 10:55am
Hi!

Is there any demo about TWebDatasSet and pictures? I'm looking on how to upload a picture to a dataset, save it and later display it.

Also, what should be the type of the field in the dataset? I'm trying to create an web app where users can upload pictures.

I checked the demos but didnt' find any info about uploading pictures to dataset.

Kind regards,
Dino
Back to Top
Wagner R. Landgraf View Drop Down
TMS Support
TMS Support
Avatar

Joined: 18 May 2010
Posts: 2550
Post Options Post Options   Quote Wagner R. Landgraf Quote  Post ReplyReply Direct Link To This Post Posted: 27 Sep 2019 at 8:21pm
Check the following example to learn how to handle blobs with XData and TMS Web Core: 
Back to Top
Dino Gomezel View Drop Down
Member
Member
Avatar

Joined: 27 Aug 2018
Posts: 88
Post Options Post Options   Quote Dino Gomezel Quote  Post ReplyReply Direct Link To This Post Posted: 02 Oct 2019 at 8:10am
I will, thank you!
Back to Top
Dino Gomezel View Drop Down
Member
Member
Avatar

Joined: 27 Aug 2018
Posts: 88
Post Options Post Options   Quote Dino Gomezel Quote  Post ReplyReply Direct Link To This Post Posted: 03 Oct 2019 at 1:33pm
Hmm.. I'm stuck :(

Here's what I did so far:

procedure TfrmNew.UpdatePicture;
var
  xhr: TJSXmlHttpRequest;
begin
  xhr := TJSXMLHttpRequest.new;
//  xhr.open('PUT', connServer.URL+'/'+string(TJSObject(wdsPobuda.CurrentData)['Slika@xdata.proxy']));
  xhr.open('PUT', connServer.URL+'/'+string('pobuda(1)/Slika'));  //<-- like this because TJSObject(wdsPobuda.CurrentData) is always empty!
  xhr.send(imgSlika.Base64Image);
end;

procedure TfrmDetails.ShowPicture;
var
  xhr: TJSXmlHttpRequest;

  procedure _Load;
  var stream: TBytesStream;
  begin
    stream := TBytesStream.Create(DecodeBase64(xhr.responseText));
    imgSlika.Picture.LoadFromStream(stream);  
  end;

begin
  xhr := TJSXMLHttpRequest.new;
//  xhr.open('GET', connServer.URL+'/'+string(TJSObject(wdsPobuda.CurrentData)['Slika@xdata.proxy']));
  xhr.open('GET', connServer.URL+'/pobuda(1)/Slika'); //<-- like this because TJSObject(wdsPobuda.CurrentData) is always empty!
  xhr.addEventListener('load', @_Load);
  xhr.send;
end;

The problems are:

1. I don't know how to encode the picture as Base64. I need to decode it because I wnt to assign the 
2. Unkown 'TBytesStream'

How to get saved data after ApplyUpdate (please note, than I'm adding a new record before calling ApplyUpdate).

I tought I could do this (simplified version):

  wdsPobuda.QueryString := '$filter=Id lt ''1''';
  wdsPobuda.Load;
  wdsPobuda.Append;
//  wdsPobuda.FieldByName('Id').AsInteger := autogenerated on insert
  wdsPobuda.FieldByName('Description').AsInteger := 'test';
  wdsPobuda.Post;
  wdsPobuda.ApplyUpdates;
  
  ShowMEssage(wdsPobuda.FieldByName('Id').AsString); <-- this shows the latest Id after the insert.

I don't know how to get the Id of the just inserted record. I need it because I want to execute the procedure UpdatePicture.



Back to Top
Wagner R. Landgraf View Drop Down
TMS Support
TMS Support
Avatar

Joined: 18 May 2010
Posts: 2550
Post Options Post Options   Quote Wagner R. Landgraf Quote  Post ReplyReply Direct Link To This Post Posted: 03 Oct 2019 at 4:42pm
What type is imgSlika?
What XData version are you using?
Back to Top
Dino Gomezel View Drop Down
Member
Member
Avatar

Joined: 27 Aug 2018
Posts: 88
Post Options Post Options   Quote Dino Gomezel Quote  Post ReplyReply Direct Link To This Post Posted: 04 Oct 2019 at 7:42am
XData: latest version (updated few days ago).

imgSlika: tried 2 ways

First try: imgSlika: TWebImageControl,
now using imgSlika: TWebDBImageControl;
Back to Top
Dino Gomezel View Drop Down
Member
Member
Avatar

Joined: 27 Aug 2018
Posts: 88
Post Options Post Options   Quote Dino Gomezel Quote  Post ReplyReply Direct Link To This Post Posted: 04 Oct 2019 at 2:00pm
To display the picture I use the TWebDBImageControl linked to a field "Slika" of the TXDataWebDataset

I execute this code:
  wdsPobuda.QueryString := '$filter=Id eq '''+IntToStr(PobudaId)+'''&$expand=Slika';
  wdsPobuda.Load;

and get this error onthe bottom of the page:

ERROR
Invalid integer value: "$ZC" | fMessage::Invalid integer value: "$ZC" fHelpContext::0
at http://localhost:8000/Okolje24/Okolje24.js [3138:12]

Please note that the query (http://localhost:3000/xdata/Pobuda?$filter=Id%20eq%20%2728%27&$expand=Slika)  executes correctly, the problem is in the displaying of the data.

I previously saved the data using this code
procedure TfrmNew.UpdatePicture;
var
  xhr: TJSXmlHttpRequest;
begin
  xhr := TJSXMLHttpRequest.new;
  xhr.open('PUT', connServer.URL+'/'+string('pobuda('+wdsPobuda.FieldByName('Id').AsString+')/Slika'));
  xhr.send(imgSlika.Base64Image);
end;

I have checked the documentation for TWebDBImageControl,but there is only a minimal description and I haven't fount an example in the XData subfolder.

What is the correct method for saving and displaying images via XDataWebDataSet?


Back to Top
Wagner R. Landgraf View Drop Down
TMS Support
TMS Support
Avatar

Joined: 18 May 2010
Posts: 2550
Post Options Post Options   Quote Wagner R. Landgraf Quote  Post ReplyReply Direct Link To This Post Posted: 07 Oct 2019 at 3:17pm
You can load the image directly into the TWebImageControl using this code:

 WebImageControl1.Url := XDataWebConnection1.URL + '/' +
    string(TJSObject(XDataWebDataset1.CurrentData)['Photo@xdata.proxy']);
Back to Top
Dino Gomezel View Drop Down
Member
Member
Avatar

Joined: 27 Aug 2018
Posts: 88
Post Options Post Options   Quote Dino Gomezel Quote  Post ReplyReply Direct Link To This Post Posted: 08 Oct 2019 at 8:10am
Done, but the picture is still missing (but no errors in browser console). For double check - here's how I save the picture:

procedure TfrmNew.UpdatePicture;
var
  xhr: TJSXmlHttpRequest;
begin
  xhr := TJSXMLHttpRequest.new;
  xhr.open('PUT', connServer.URL+'/'+string('pobuda('+wdsPobuda.FieldByName('Id').AsString+')/Slika'));
  xhr.send(imgSlika.Base64Image);
end;

This is called on the AplyUpdates event:

procedure TfrmNew.wdsPobudaAfterApplyUpdates(Sender: TDataSet; Info: TResolveResults);
begin
  UpdatePicture;
  ModalResult := mrOk;
end;

After execution the DB record is filled with text (Base64 image data I presume :) )

I load it later (in another form) with this code:

procedure TfrmDetails.wdsPobudaAfterOpen(DataSet: TDataSet);
begin
  imgSlika2.Url := connServer.URL + '/' +string(TJSObject(wdsPobuda.CurrentData)['Slika@xdata.proxy']);
end;

I checked the browser console for any errors, but ther seems everything ok - just the picture is missing.
Back to Top
Wagner R. Landgraf View Drop Down
TMS Support
TMS Support
Avatar

Joined: 18 May 2010
Posts: 2550
Post Options Post Options   Quote Wagner R. Landgraf Quote  Post ReplyReply Direct Link To This Post Posted: 09 Oct 2019 at 2:54pm
You should send the raw binary image to the server, not the base64 value. This is what you should use:

  function Base64ToArrayBuffer(str: string): TJSArrayBuffer;
  var
    BufView: TJSUInt8Array;
    BinaryString: string;
    I: Integer;
  begin
    BinaryString := window.atob(str);
    Result := TJSArrayBuffer.new(Length(BinaryString));
    BufView := TJSUInt8Array.new(Result);
    for I := 0 to Length(BinaryString) - 1 do
      BufView := TJSString(BinaryString).charCodeAt(I);
  end;

  xhr.send(Base64ToArrayBuffer(WebImageControl1.Base64Image));
Back to Top
Dino Gomezel View Drop Down
Member
Member
Avatar

Joined: 27 Aug 2018
Posts: 88
Post Options Post Options   Quote Dino Gomezel Quote  Post ReplyReply Direct Link To This Post Posted: 10 Oct 2019 at 10:08am
It's working!

I just needed to fix a little bit the code:

Wrong:
BufView := TJSString(BinaryString).charCodeAt(I);

correct:
BufView := TJSString(BinaryString).charCodeAt(I);
Back to Top
Dino Gomezel View Drop Down
Member
Member
Avatar

Joined: 27 Aug 2018
Posts: 88
Post Options Post Options   Quote Dino Gomezel Quote  Post ReplyReply Direct Link To This Post Posted: 10 Oct 2019 at 10:09am
Mistake - correct is:

BufView := TJSString(BinaryString).charCodeAt(I);
Back to Top
Dino Gomezel View Drop Down
Member
Member
Avatar

Joined: 27 Aug 2018
Posts: 88
Post Options Post Options   Quote Dino Gomezel Quote  Post ReplyReply Direct Link To This Post Posted: 10 Oct 2019 at 10:10am
I found a bug in the forum - you cannot add text with square brackets :)

Replace the curly brackets witj the square brackets: BufView{I}
Back to Top
Bart Holvoet View Drop Down
TMS Support
TMS Support
Avatar

Joined: 18 May 2010
Posts: 2162
Post Options Post Options   Quote Bart Holvoet Quote  Post ReplyReply Direct Link To This Post Posted: 10 Oct 2019 at 10:39am
Originally posted by Dino Gomezel

I found a bug in the forum - you cannot add text with square brackets :)

Replace the curly brackets witj the square brackets: BufView{I}

Note that you can uncheck the BBCodes checkbox below the message box to enable the use of square brackets.

Example:
BufView[I] := TJSString(BinaryString).charCodeAt(I);
Back to Top
Dino Gomezel View Drop Down
Member
Member
Avatar

Joined: 27 Aug 2018
Posts: 88
Post Options Post Options   Quote Dino Gomezel Quote  Post ReplyReply Direct Link To This Post Posted: 10 Oct 2019 at 10:40am
ops.. :)
Back to Top
Dino Gomezel View Drop Down
Member
Member
Avatar

Joined: 27 Aug 2018
Posts: 88
Post Options Post Options   Quote Dino Gomezel Quote  Post ReplyReply Direct Link To This Post Posted: 08 Nov 2019 at 1:35pm
I think the code has a strange thing

  function Base64ToArrayBuffer(str: string): TJSArrayBuffer;
  var
    BufView: TJSUInt8Array;
    BinaryString: string;
    I: Integer;
  begin
    BinaryString := window.atob(str);
    Result := TJSArrayBuffer.new(Length(BinaryString));
    BufView := TJSUInt8Array.new(Result);
    for I := 0 to Length(BinaryString) - 1 do
      BufView := TJSString(BinaryString).charCodeAt(I);
  end;

Why the part in red? And also has an error in line BufView := TJSString(. 
It does nothing to the result? 

Can you rewrite the procedure, because I don't know what to do with the red part - should I just remove it?
Back to Top
Wagner R. Landgraf View Drop Down
TMS Support
TMS Support
Avatar

Joined: 18 May 2010
Posts: 2550
Post Options Post Options   Quote Wagner R. Landgraf Quote  Post ReplyReply Direct Link To This Post Posted: 10 Nov 2019 at 11:42pm
No, it's needed to convert the characters to actual byte value (a string to an array of bytes).
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down